1. 程式人生 > >關於印表機狀態的獲取

關於印表機狀態的獲取

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

        關於這個需求很早就考慮了,一直沒敢下手,也不是不敢,是之前下過一次手但是沒有成功。一直過了幾個月騰出一些空閒來解決這個問題。另外說明一下,截止到目前對於這個需求我還沒有一個完全的解決方案。這篇也只是捋下思緒。

        關於印表機狀態的問題我在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

           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述