• 关于打印机状态的获取


            关于这个需求非常早就考虑了,一直没敢下手,也不是不敢,是之前下过一次手可是没有成功。一直过了几个月腾出一些空暇来解决问题。另外说明一下,截止到眼下对于这个需求我还没有一个全然的解决方式。这篇也仅仅是捋下思绪。

            关于打印机状态的问题我在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 ", status);

        printf("Hello world ");

    }

     

    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 ");

            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 ");

            goto bugout;

        }

     

        *status = (unsigned int)byte;

        stat = 0;

        DBG("read actual device_status successfully fd=%d ", 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这句话从打印机到屏幕的流程走通,这个状态的问题基本就能够宣告攻克了。可是这个仅仅是设想,真正实现起来并没有那么easy。这是一个开篇。 


    參考文档:

    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

  • 相关阅读:
    Web系统可复用架构
    asp.net mvc 2 简简单单做开发 实现基本数据操作操作RepositoryController<T>
    asp.net mvc 2 简简单单做开发 使用DataContext扩展方法Find<TEntity>(TEntity obj) 遇到的问题
    asp.net mvc 2 简简单单做开发 自定义DropdownList控件
    asp.net mvc 2 DisplayTemplates 的使用
    linq to sql 扩展方法
    asp.net mvc 2 简简单单做开发 通用增删改基本操作通用页面
    asp.net mvc 2 简简单单做开发 自定义Controller基类
    JNLP启动相关的东东
    easyexcel往已存在的excel文件里追加数据
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/3780643.html
Copyright © 2020-2023  润新知