关于打印机状态的获取

本文详细探讨了在Linux环境中获取打印机状态的方法,并通过实验验证了从Linux标准USB打印机驱动和HP Device Manager源码入手的可行性。文章介绍了如何利用libusb库获取打印机状态,并通过HPLIP源码进一步深入研究。重点在于解析打印机的各种状态码及其背后的含义,为后续的打印机状态监测和故障排查提供了技术支持。

        关于这个需求很早就考虑了,一直没敢下手,也不是不敢,是之前下过一次手但是没有成功。一直过了几个月腾出一些空闲来解决这个问题。另外说明一下,截止到目前对于这个需求我还没有一个完全的解决方案。这篇也只是捋下思绪。

        关于打印机状态的问题我在stackoverflow上也作过提问,结果问题就被删除了,原因有二有人说这个问题是硬件上的问题,所以不在stackoverflow所讨论的范围。另一个或许是自己的英文着实烂的不行了,问题都解释不清楚。

        由于一直没有死心,所以在平时无聊的时候也会掏出手机搜索一番,当时唯一的收获是参考文档[1]中提到的USBHostPrinterGetStatus(),这个神奇的函数没有写任何来源,但作者将其描述成是可以获取打印机状态的,我着实有那么一点兴奋。但是苦于没有来源,有点不知所措。不过我还是将其作为一个方向进行了深挖了的。顺便找到了[3]-是和[1]差不多的英文版本,以及[2]这个现存的这个函数。从总体来说Linux中并没有这个函数,不知道写论文的那个是不是先有论文又做的实验。这个似乎是一个裸机程序,在我找到[5]这样专业文档的时候,这个几个状态是USB通信协议中就已经规定了的。更加确定这个函数目前深究下去是一个死路,不过以后做裸机的时候可以重新了解。

        以上是走过的错路,下面说下我这次走能的小路:1.Linux中标准的USB打印机驱动着手;2.HP Device Manager入手。前后者都小有所获,以下逐个来分析。逐个分析前先把打印机在Windows下的各种问题的状态列表记录一下,话说收集这个可不是一个简单的事,首先是锁定打印机型号然后制造这种故障,使得PC上能够显示出对于的状态对话框。(到目前为至12-14还并不是官方的文字,因为制造该故障的条件一直不具备)

 

NO

中文

英文

limit

1

无法与打印机通信

Unable to Communicate with Printer

E

2

出纸盒已关闭

Output Tray Closed

E

3

门己打开

Door Open

E

4

缺纸

Out of Paper

E

5

卡纸

Paper Jam

E

6

墨盒故障-黑色

Ink Cartridge Failure

E

7

墨盒故障-三色

-

E

8

墨盒故障-黑色-三色

-

E

9

墨盒丢失

Ink Cartrideges Missing

E

10

单墨盒模式-缺黑色

Single Ink Cartridge Mode

W

11

单墨盒模式-缺彩色

-

W

12

无墨  黑色

x

E

13

无墨  彩色

x

E

14

无墨  黑色-彩色

x

E

15

已经安装HP保护墨盒

HP Protected Cartridge Installed

I

16

检测到使用过的或仿制墨盒

Used or Counterfeit Cartridge Detected

I

(着实不知用wps转换成的mht格式再粘贴到blog上后表格会变成虚的)

方向1是从usblp.c中的驱动着手

结合打印机内核驱动源码usblp.c以及Usb协议[5]规定打印机状态:

 

驱动的具体实现是在ioctl方法中的LPGETSTATUS命令中返回的状态,经过实验确实能获得一个比较显著的状态Out of Paper/Paper Empty这样一个状态,应用层的代码如下:

#include <stdio.h>

#include <sys/types.h>

#include <unistd.h>

#include <sys/wait.h>

#include <dirent.h>

#include <string.h>

#include <signal.h>

#include <fcntl.h>

#include <sys/ioctl.h>

#include <linux/lp.h>

 

void getDeviceStatus(int fd) {

    if(fd < 0)

        return;

    int status = 0;

    ioctl(fd, LPGETSTATUS, &status);

    printf("%x\n", status);

    printf("Hello world\n");

}

 

int main()

{

    int fd = open("/dev/usb/lp0", O_RDWR);

    getDeviceStatus(fd);

    close(fd);

    return 0;

}


不过遗憾的是,这个状态码的规律是这样的:正常0x18;缺纸 0x38;其它统统是0x10。等于我现在只拿到了一个状态。我的高兴劲头仅仅持续了几分钟。

方向2HP Device Manager的源码入手

如下图,该软件可以显示更多的状态,且还是开源的hplib。从实验得出该神器可以获得以上列出的每个状态。

推导一下这个神器的真实身份:HP Device Manager -> hp-boolbox -> hplib最终确定了hplib。hplib的架构是这样的:


Hplip的源码中有这么一段,用到libusb.可以获取打印机状态:

static int device_status(int fd, unsigned int *status)

{

    libusb_device_handle *hd;

    int interface;

    int len, stat=1;

    unsigned char byte;

 

    hd = fd_table[fd].hd;

    interface = fd_table[fd].interface;

 

    if (hd == NULL)

    {

        BUG("invalid device_status state\n");

        goto bugout;

    }

 

    len = libusb_control_transfer(hd,

            LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE/* bmRequestType */

            LIBUSB_REQUEST_CLEAR_FEATURE,        /* bRequest */

            0,        /* wValue */

            interface, /* wIndex */

            &byte, 1, LIBUSB_CONTROL_REQ_TIMEOUT);

 

    if (len < 0)

    {

        BUG("invalid device_status: %m\n");

        goto bugout;

    }

 

    *status = (unsigned int)byte;

    stat = 0;

    DBG("read actual device_status successfully fd=%d\n", fd);

 

bugout:

    return stat;

}


就这几行代码,但却难住了我,还是静下心来看看<libusb Developers Guide>。回头再来继续。从hplib追踪到APDK(hp官方支持的非PC平台的打印驱动),其中包含了与打印通信以及打印机的错误代码。只Google出这么一个好的资料《APDK Developers Guide Reference Manual》。这个《hpmud》也相当好,可以清晰的显示出hplip源码结构。

$ sudo apt-get install libhpmud-dev

标准头文件hpmud.h,基于这个开发。Hp.c就是一个独立的基于libhpmud的程序。我在libhpmud中添加的这个调试信息在运行hp.c的时候可以看到,但是在运行hp-toolbox的时候根本没有反应,又有点怀疑,它的底层没有用libhpmud这个库。

如果能将Door open这句话从打印机到屏幕的流程走通,这个状态的问题基本就可以宣告解决了。但是这个只是设想,真正实现起来并没有那么容易。这是一个开篇。 


参考文档:

1.《基于Android平台的无线打印模块设计

2.USBHostPrinterGetStatus 

3.USB Printer Class on an Embedded Host

4.How to retrieve USB printer status?

5.Universal Serial Bus Device Class Definition for Printing Devices

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

袁保康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值