Linux 网络打印机

Wikis > Linux 网络打印机

1.背景交代

Linux系统中主要的打印组件有CUPS 和LDP,本文记录了在openwrt系统上基于cups的samba printer的安装配置方法。

High quality drivers for Canon, Epson, Lexmark, Sony, Olympus, and PCL printers for use with CUPS, Ghostscript, Foomatic, and GIMP.

 操作系统:openwrt

2.基本组件安装

(1)cups:可以到cups官网上下载。

(2)ghostscript:(源码站点:http://iweb.dl.sourceforge.net/project/ghostscript/GPL%20Ghostscript/

使用该脚本下载ghostscript-9.06源码,并编译出pc上使用的一些工具拷贝到sdk-ghostscript/files/目录下供sdk编译时使用,脚本内容见附件:
将以上单独编译出x86架构下工具放到makefile中:
001-cross_compile.patchMakefile.dat
将以上代码放到package/gostscript/目录下相应位置即可解决x86架构下工具的生成在32位和64位下交叉使用时编译出错的问题(实际过程是生成文件系统制作工具的mkfs_0时需要使用x86架构,而最终生成的gs却需要是arm架构,而这两个文件都依赖了一些相同的.o文件,这些文件需要生成两套:一套x86结构的一套arm架构的,以上patch和makefile就为解决这一操作而做的修改)。
(3)gutenprint:
将gutenprint放在sdk原来的位置,即:

(4)hplip: 将hplip放到package目录下编译即可
 

 3.修改配置文件

vim /home/nickli/puma_sdk/skysoft/qsdk_package/puma.config
在文件末尾增加以下内容:
#
#Net Print
#
CONFIG_PACKAGE_cups=y
CONFIG_PACKAGE_ghostscript=y
#CONFIG_PACKAGE_ghostscript-fonts-std=y
#CONFIG_PACKAGE_gutenprint-cups=y
#CONFIG_PACKAGE_lcms2=y
#CONFIG_PACKAGE_libfreetype=y
#CONFIG_PACKAGE_libiconv=y
#CONFIG_PACKAGE_libtiff=y
#CONFIG_PACKAGE_fontconfig=y
CONFIG_PACKAGE_gutenprint=y
CONFIG_PACKAGE_gutenprint-ppd=y
CONFIG_PACKAGE_hplip=y
CONFIG_PACKAGE_hplip-ppd=y
增加usb内核支持:
CONFIG_PACKAGE_kmod-usb-printer=y
CONFIG_PACKAGE_kmod-usb-uhci=y
CONFIG_PACKAGE_usbutils=y
否则无法正确检测到USB打印机。
解决问题而加:
CONFIG_PACKAGE_libijs=y
CONFIG_PACKAGE_glib2=y
CONFIG_PACKAGE_libpcre=y
CONFIG_PACKAGE_cups-bjnp=y
CONFIG_PACKAGE_cups-bsd=y
CONFIG_PACKAGE_cups-ppdc=y
CONFIG_PACKAGE_ghostscript-gnu-gs-fonts-other=y
CONFIG_PACKAGE_liberation-fonts=y
CONFIG_PACKAGE_openprinting-cups-filters=y
CONFIG_PACKAGE_ubuntu-fonts=y
CONFIG_PACKAGE_poppler=y
CONFIG_PACKAGE_qpdf=y
实际上编译选项如下:
#samba print
#CONFIG_PACKAGE_libpopt=y
#CONFIG_PACKAGE_samba3=y
#CONFIG_SAMBA3_CONFIG_DEBUG=y
#CONFIG_SAMBA3_CONFIG_PRINTING=y
#CONFIG_SAMBA3_CONFIG_SMALLER=y
#samba36
#CONFIG_PACKAGE_samba36-server=y
#CONFIG_PACKAGE_SAMBA_MAX_DEBUG_LEVEL=-1
#samba3
CONFIG_PACKAGE_samba3=y
CONFIG_SAMBA3_CONFIG_DEBUG=y
CONFIG_SAMBA3_CONFIG_PRINTING=y
#########net print
##cups printer
#CONFIG_PACKAGE_kmod-usb-printer=y
CONFIG_PACKAGE_kmod-usb-uhci=y
CONFIG_PACKAGE_usbutils=y
ONFIG_PACKAGE_kmod-usb-ohci=y
##add for the jpeg and pdf printing
CONFIG_PACKAGE_cups=y
CONFIG_PACKAGE_foomatic-filters=y
CONFIG_PACKAGE_ghostscript=y
CONFIG_PACKAGE_ghostscript-fonts-std=y
CONFIG_PACKAGE_gutenprint-cups=y
CONFIG_PACKAGE_lcms2=y
CONFIG_PACKAGE_libfreetype=y
CONFIG_PACKAGE_libiconv=y
CONFIG_PACKAGE_libtiff=y
CONFIG_PACKAGE_fontconfig=y
CONFIG_PACKAGE_libusb=y
#add for hplip
CONFIG_PACKAGE_hplip=y
CONFIG_PACKAGE_hplip-ppd=y

samba安装配置

参考资料:https://wiki.samba.org/index.php/Samba_as_a_print_server

cups samba printing:http://www.openprinting.org/download/kpfeifle/SambaPrintHOWTO/Samba-HOWTO-Collection-3.0-PrintingChapter-11th-draft.html

离线文档:

 

实际步骤:

(1)增加编译配置项:

CONFIG_PACKAGE_libpopt=y

CONFIG_PACKAGE_samba3=y

CONFIG_SAMBA3_CONFIG_DEBUG=y

CONFIG_SAMBA3_CONFIG_PRINTING=y

CONFIG_SAMBA3_CONFIG_SMALLER=y

 

 

版本检查:

#opkg list-installed |grep cups

cups – 1.4.4-10

gutenprint-cups – 5.2.9-1

 

# opkg list-installed |grep ghost

ghostscript – 9.06-3

ghostscript-fonts-std – 8.11-1

使用新版cups时相关软件版本参考:《cups打印使用方法》附件。

至此,老版本的cups+samba移植成功。

 

4.测试cups功能

启动cups时出现如下错误提示:

/usr/lib/cups/backend/usb: can’t load library ‘libusb-0.1.so.4’

分析:sdk中安装的libusb为1.0.9版的,而1.4.4版cups依赖的0.1版的,查看sdk发现里面有两个libusb包,而默认的编译选项将libusb-1.0打开了,而没有打开libusb,所以应该将libusb打开就可以了。CONFIG_PACKAGE_libusb-1.0=y

解决方法:在sdk中将libusb开关打开

CONFIG_PACKAGE_libusb=y

结果:问题解决,cups能工作。

查看某二进制文件依赖组件命令

 readelf -d cupsd

 

5.测试samba功能

文件共享功能正常。

注意,使用老版本samba时,启动脚本里面账户添加命令得恢复原样:

(老版使用) #smbpasswd $name $passwd

(新版使用)(echo “$passwd”;sleep 1; echo “$passwd”)|smbpasswd -as $name

samba print功能验证:

/etc/config/samba配置:

config print

option printer ‘samba-printer’

option path ‘/mnt/part1/sambaspool’

option guest_ok ‘1’

option printable ‘1’

#/etc/init.d/samba restart

#vim /etc/samba/smb.conf

[samba-printer]

path = /var/spool/samba

browsable = yes

guest ok = yes

printable = yes

use client driver = yes

客户端访问samba时,出现找不到驱动程序,需要在本地手动安装驱动,并且手动安装了驱动后也无法打印文件。

优化:

(1)添加打印机驱动到/etc/samba/drivers/目录下;

(2)在/etc/samba/smb.conf.template中添加以下红色标注的内容:

[global]

netbios name = |NAME|

workgroup = |WORKGROUP|

server string = |DESCRIPTION|

syslog = 10

encrypt passwords = true

passdb backend = smbpasswd

obey pam restrictions = yes

socket options = TCP_NODELAY

unix charset = |CHARSET|

preferred master = yes

os level = 20

security = user

guest account = nobody

map to guest = bad user

smb passwd file = /etc/samba/smbpasswd

interfaces = |INTERFACES|

printing = cups

printcap name = cups

load printers = yes

[print$]

comment = Printer driver

path = /etc/samba/drivers

browseable = yes

gueset ok = yes

参考资料:http://yuanbin.blog.51cto.com/363003/115768

注意[print$]必须这样,这个共享仅仅为容纳samba打印机的驱动文件,客户端PC上是看不到这个目录的。

最终配置文件如下:

[global]

netbios name = openwrt

workgroup = WORKGROUP

server string = Samba on OpenWrt

syslog = 10

encrypt passwords = true

passdb backend = smbpasswd

obey pam restrictions = yes

socket options = TCP_NODELAY

unix charset = UTF-8

preferred master = yes

os level = 20

security = user

guest account = nobody

map to guest = bad user

smb passwd file = /etc/samba/smbpasswd

interfaces = 127.0.0.1/255.0.0.0 lo 192.168.1.1/255.255.255.0 br-lan

printing = cups

printcap name = cups

load printers = yes

[print$]

comment = Printer driver

path = /etc/samba/drivers

browseable = yes

gueset ok = yes

[ftp-test]

path = /mnt/part1/ftp-test

valid users = admin

guest ok = no

create mask = 0755

directory mask = 0755

read list =

write list = admin

[HP_Deskjet_1000_J110_series]

path = /var/spool/samba

browsable = yes

guest ok = yes

printable = yes

public = yes

这样配置之后,通过客户端手动添加过打印机驱动的PC能正常打印文件,而其他PC依然提示找不到打印机驱动。

 

参考:NAS版samba-print配置信息。

 

NAS版信息:

/etc/config/samba 文件内容:

config ‘global’

option ‘netbios’ ‘openwrt’

option ‘share_folder_num’ ’30’

option ‘enable’ ‘1’

config ‘print’

list ‘printer’ ‘HP_Deskjet_1000_J110_series’

 

/etc/samba/smb.conf文件内容:

[global]

netbios name = openwrt

workgroup = OpenWrt

server string = Samba on OpenWrt

syslog = 10

encrypt passwords = true

passdb backend = smbpasswd

obey pam restrictions = yes

socket options = TCP_NODELAY

unix charset = UTF-8

preferred master = yes

os level = 20

security = user

guest account = nobody

map to guest = bad user

smb passwd file = /etc/samba/smbpasswd

interfaces = 127.0.0.1/255.0.0.0 lo 192.168.2.1/255.255.255.0 br-lan

[HP_Deskjet_1000_J110_series]

path = /var/spool/samba

browsable = yes

guest ok = yes

printable = yes

use client driver = yes

实际上在cups管理界面上添加成功的打印机的名字(URL中存在的名字)写入/etc/config/samba配置文件中”config print”节就可以了,形式如下:

config print

list ‘printer’ ‘HP_Deskjet_1000_J110_series_USB_CN35719JFF05YD_HPLIP’

然后,/etc/init. d/samba启动脚本会根据该信息将该打印机共享出来。在客户端的确还需要手动安装打印机驱动,NAS版samba print并没有解决该问题。安装好驱动后,局域网中的PC客户端就可以通过访问服务器samba地址找到samba打印机来手动安装好对应型号的打印机驱动,之后就可以正常打印文件了。

但是注意,在samba打印配置节添加的打印机名称,一定要和cups界面上添加的打印机的名称一致。因为对于同一台打印机在cups管理界面上可以存在不同的名称,这要看你在添加打印时选择了哪个后端来部署打印机。比如安装了cups,并安装了hplip,那么可能在界面上查打印机时会出现两种打印机,一种是cups直接访问的,一种是通过hplip来访问的,这两种名称会有所不同,如:

netprinter-1

samba print 服务配置体验到此结束!

 

6.cups+samba 配置

https://forums.gentoo.org/viewtopic.php?t=110931

 

http://www.tldp.org/HOWTO/Debian-and-Windows-Shared-Printing/sharing_with_windows.html

 

openprinting:http://www.linuxfoundation.org/collaborate/workgroups/openprinting

https://wiki.samba.org/index.php/Samba_as_a_print_server

 

7.使用方法

cups命令行工具:

http://docs.oracle.com/cd/E26502_01/html/E29012/gllgm.html

如何使用 lpadmin 命令设置打印机

http://liuyu.ie.cnu.edu.cn/2014/E56344_01/html/E53848/gllia.html

8.cups接口编写

为将以上网络打印功能集成到你自己的项目WebGUI中,那么需要对打印机的基本控制进行接口整理,如openwrt官网WebGUI使用的LUA来实现的,那么需要实现Lua接口。本项目中前台和后台之间交互使用的C语言编写的cgi,所以主要是使用cups的基础接口来封装了一系列的Cgi接口。

cups接口官方文档:

http://sourcecodebrowser.com/cups/1.4.6/cups_8h.html

 

接口笔记:

 

接口测试:

序号 接口名称 功能描述 状态
1 GetDests 功能完好
2 GetDestAttrs 功能完好
3 GetDevices 功能完好
4 GetPPDs 功能完好
5 SetDefaultPrinter
6 DeletePrinter 功能完好
7 EnablePrinter 功能完好
8 SetPrinterDevice 功能完好
9 SetPrinterFile
10 SetPrinterInfo 功能完好
11 SetPrinterLocation location为getdevices返回的makeandmodel参数值, 功能完好
12 SetPrinterModel 功能完好
13 GetJobs 功能完好
14 JobOperate 功能完好
15 PrintTestPage

注:

(1)jobs状态5–processing;9–complete;3–pending。

本项目cups接口调用逻辑:

##添加打印机

(1)进入net printer界面时首先调用Getdevices接口获取连接到服务器上的所有的打印机设备信息;

(2)然后调用GetBrands获取系统支持的所有打印机品牌列表,当选择好品牌后再调用GetPPDs接口获取所有打印机的驱动文件;

(因为Cgi传递到前端的数据长度限制,导致无法将所有信息一次性传递到前端,所以将获取PPD文件过程分成以上两个步骤)

(3)找到目标驱动文件后,在点击Apply时调用SetPrinterDevice设置打印机URI,然后调用SetPrinterModel将PPD文件添加到打印机中;

(setprinterModel时要区分是通过直接选择PPD描述信息,还是通过本地上传PPD文件来添加打印机的,前端后端都需要相应的判断处理)

(4)当第三步都成功后,需要调用EnabePrinter接口将该打印机添加到cups-server中;

##管理打印机

(5)打印机列表界面:进入打印机列表时调用GetDestAttrs获取所有的打印机详细信息;

(6)打印机列表界面:在点击某个打印机后,在其私有的界面中点击“Print Test Page”后调用PrintTestPage接口进行打印测试(暂时去掉该功能);

(7)打印机列表界面:在点击某个打印机后,在其私有的界面中点击“Delete Printer”后调用DeletePrinter接口将该打印机删除;

##管理打印作业

(8)注意以各个步骤中,需要传递的参数printername为Getdevices接口返回的DeviceInfo标定的字符串将空格替换成下划线后的值。

 

其他接口:

SetDefaultPrinter:当系统中添加了多个打印机时,调用该接口来设置系统默认打印机,打印流会指向该打印机。

 

AddPrinter流程:

getDevices()

ret= setPrinterDevice(name,device_uri)

ret = setPrinterModel(name,ppd)

if(ret ==true){

setPrinterLocation(name, device-make-and-model)

setPrinterInfo()

enablePrinter()

}

jobs状态检查:

预期目标:第三个打印作业正在进行时,其状态应与第一二个作业的状态不一样:

{ “JobsInfo”: [

{ “Title”: “测试页”, “User”: “test”, “Format”: “application\/octet-stream”, “Priority”: 50, “CreationTime”: “Wed Jun 24 07:58:48 2015\n”, “ProcessingTime”: “Wed Jun 24 07:58:48 2015\n”, “CompletedTime”: “Wed Jun 24 07:59:05 2015\n”, “Id”: 1, “State”: 9, “Dest”: “HP_Deskjet_1000_J110_series_USB_CN35719JFF05YD_HPLIP”, “Size”: 138, “PrinterStateMessage”: “” },

{ “Title”: “Microsoft Word – 管理日志.docx”, “User”: “test”, “Format”: “application\/octet-stream”, “Priority”: 50, “CreationTime”: “Wed Jun 24 08:09:18 2015\n”, “ProcessingTime”: “Wed Jun 24 08:09:18 2015\n”, “CompletedTime”: “Wed Jun 24 08:09:34 2015\n”, “Id”: 2, “State”: 9, “Dest”: “HP_Deskjet_1000_J110_series_USB_CN35719JFF05YD_HPLIP”, “Size”: 109, “PrinterStateMessage”: “” },

{ “Title”: “Microsoft Word – 管理日志.docx”, “User”: “test”, “Format”: “application\/octet-stream”, “Priority”: 50, “CreationTime”: “Wed Jun 24 08:15:15 2015\n”, “ProcessingTime”: “Wed Jun 24 08:15:15 2015\n”, “Id”: 3, “State”: 5, “Dest”: “HP_Deskjet_1000_J110_series_USB_CN35719JFF05YD_HPLIP”, “Size”: 596, “PrinterStateMessage”: “” }

] }

对比结果:1、2作业的state=9(complete),而3作业的state=5(processing/active)

预期目标:第三个打印作业完成后,其状态应与第一二个作业的状态一样。

{ “JobsInfo”: [

{ “Title”: “测试页”, “User”: “test”, “Format”: “application\/octet-stream”, “Priority”: 50, “CreationTime”: “Wed Jun 24 07:58:48 2015\n”, “ProcessingTime”: “Wed Jun 24 07:58:48 2015\n”, “CompletedTime”: “Wed Jun 24 07:59:05 2015\n”, “Id”: 1, “State”: 9, “Dest”: “HP_Deskjet_1000_J110_series_USB_CN35719JFF05YD_HPLIP”, “Size”: 138, “PrinterStateMessage”: “” },

{ “Title”: “Microsoft Word – 管理日志.docx”, “User”: “test”, “Format”: “application\/octet-stream”, “Priority”: 50, “CreationTime”: “Wed Jun 24 08:09:18 2015\n”, “ProcessingTime”: “Wed Jun 24 08:09:18 2015\n”, “CompletedTime”: “Wed Jun 24 08:09:34 2015\n”, “Id”: 2, “State”: 9, “Dest”: “HP_Deskjet_1000_J110_series_USB_CN35719JFF05YD_HPLIP”, “Size”: 109, “PrinterStateMessage”: “” },

{ “Title”: “Microsoft Word – 管理日志.docx”, “User”: “test”, “Format”: “application\/octet-stream”, “Priority”: 50, “CreationTime”: “Wed Jun 24 08:15:15 2015\n”, “ProcessingTime”: “Wed Jun 24 08:15:15 2015\n”, “CompletedTime”: “Wed Jun 24 08:16:23 2015\n”, “Id”: 3, “State”: 9, “Dest”: “HP_Deskjet_1000_J110_series_USB_CN35719JFF05YD_HPLIP”, “Size”: 596, “PrinterStateMessage”: “” }

] }

对比结果:作业3完成后其state和1、2一致都为9(state=9)

 

GetDevices返回值:

{ “DevInfo”: [

{ “DeviceNum”: 0, “DeviceClass”: “direct”, “DeviceId”: “MFG:HP;MDL:Deskjet 1000 J110 series;CMD:PCL,DW-PCL,DESKJET,DYN;CLS:PRINTER;DES:CH340D;CID:HPIJVIPAV1;LEDMDIS:USB#07#01#02,USB#FF#04#01;SN:CN35719JFF05YD;S:038000C484001021002c1f00014c2880028;J:                    ;Z:0102,05033c2900bf49,0600,0c0,0e00000000,0f00000000,10000008000008,12000,143,150,16361a33c2000316da19fa0003,17000000000000;”, “DeviceInfo“: “HP Deskjet 1000 J110 series”, “DeviceMakeAndModel”: “HP Deskjet 1000 J110 series”, “DeviceUri“: “usb:\/\/HP\/Deskjet%201000%20J110%20series?serial=CN35719JFF05YD”, “DeviceLocation”: “” },

{ “DeviceNum”: 1, “DeviceClass”: “direct”, “DeviceId”: “MFG:HP;MDL:Deskjet 1000 J110 series;CLS:PRINTER;DES:Deskjet 1000 J110 series;SN:CN35719JFF05YD;”, “DeviceInfo“: “HP Deskjet 1000 J110 series USB CN35719JFF05YD HPLIP”, “DeviceMakeAndModel“: “HP Deskjet 1000 J110 series”, “DeviceUri“: “hp:\/usb\/Deskjet_1000_J110_series?serial=CN35719JFF05YD”, “DeviceLocation”: “” }

] }

 

GetDestAttrs返回值:

{ “DevInfo”: [

{ “DeviceNum”: 0, “DeviceClass”: “direct”, “DeviceId”: “MFG:HP;MDL:Deskjet 1000 J110 series;CMD:PCL,DW-PCL,DESKJET,DYN;CLS:PRINTER;DES:CH340D;CID:HPIJVIPAV1;LEDMDIS:USB#07#01#02,USB#FF#04#01;SN:CN35719JFF05YD;S:038000C484001021002c1f00014c2880028;J: ;Z:0102,05033c2900bf49,0600,0c0,0e00000000,0f00000000,10000008000008,12000,143,150,16361a33c2000316da19fa0003,17000000000000;”, “DeviceInfo“: “HP Deskjet 1000 J110 series”, “DeviceMakeAndModel”: “HP Deskjet 1000 J110 series”, “DeviceUri”: “usb:\/\/HP\/Deskjet%201000%20J110%20series?serial=CN35719JFF05YD”, “DeviceLocation”: “” },

{ “DeviceNum”: 1, “DeviceClass”: “direct”, “DeviceId”: “MFG:HP;MDL:Deskjet 1000 J110 series;CLS:PRINTER;DES:Deskjet 1000 J110 series;SN:CN35719JFF05YD;”, “DeviceInfo“: “HP Deskjet 1000 J110 series USB CN35719JFF05YD HPLIP”, “DeviceMakeAndModel”: “HP Deskjet 1000 J110 series”, “DeviceUri”: “hp:\/usb\/Deskjet_1000_J110_series?serial=CN35719JFF05YD”, “DeviceLocation”: “” }

] }

打印机添加流程:

getDevices()

ret= setPrinterDevice(name,device_uri)

ret = setPrinterModel(name,ppd)

if(ret ==true){

setPrinterLocation(name, device-make-and-model)

setPrinterInfo()

enablePrinter()

}

需要参数:

PrinterName:HP_Deskjet_1000_J110_series_USB_CN35719JFF05YD_HPLIP [将DeviceInfo的值,字符串中的空格替换成下划线作为打印机的名字]

RrinterUri:hp:/usb/Deskjet_1000_J110_series?serial=CN35719JFF05YD            [该参数必须]

PPD(Model):hp-deskjet_1000_j110_series.ppd.gz      [通过GetPPDs接口获取]

Location:HP Deskjet 1000 J110 series                                 [任意字符串都可以,默认设置成”Local Printer”]

Info:HP Deskjet 1000 J110 series USB CN35719JFF05YD HPLIP [任意字符串都可以]

通过以上信息添加打印机(不能打印)后调用GetDestAttrs后返回值如下:

{ “PrinterList“: [ { “PrinterIsAcceptingJobs“: 1, “PrinterIsShared“: 1, “PrinterState“: 5, “PrinterStateMessage“: “\/usr\/lib\/cups\/backend\/hp failed”, “PrinterName“: “HP_Deskjet_1000_J110_series_USB_CN35719JFF05YD_HPLIP”, “PrinterLocation“: “HP Deskjet 1000 J110 series”, “PrinterInfo“: “HP_Deskjet_1000_J110_series_USB_CN35719JFF05YD_HPLIP”, “DeviceUri“: “hp:\\\/usb\\\/Deskjet_1000_J110_series?serial=CN35719JFF05YD”, “PrinterMakeAndModel“: “HP Deskjet 1000 j110 Series, hpcups 3.13.4” } ] }

通过cups管理界面添加打印机(能打印)后调用GetDestAttrs后返回值如下:

{ “PrinterList“: [ { “PrinterIsAcceptingJobs“: 1, “PrinterIsShared“: 1, “PrinterState“: 3, “PrinterStateMessage“: “ready to print”, “PrinterName“: “HP_Deskjet_1000_J110_series_USB_CN35719JFF05YD_HPLIP”, “PrinterLocation“: “Local Printer”, “PrinterInfo“: “HP Deskjet 1000 J110 series”, “DeviceUri“: “hp:\/usb\/Deskjet_1000_J110_series?serial=CN35719JFF05YD”, “PrinterMakeAndModel“: “HP Deskjet 1000 j110 Series, hpcups 3.13.4” } ] }

可见:DeviceUri的值,前者多了斜线。

修改URI:hp:\/usb\/Deskjet_1000_J110_series?serial=CN35719JFF05YD 为:URI:hp:/usb/Deskjet_1000_J110_series?serial=CN35719JFF05YD

添加后(可打印)调用GetDestAttrs后返回值如下:

{ “PrinterList“: [ { “PrinterIsAcceptingJobs“: 1, “PrinterIsShared“: 1, “PrinterState“: 3, “PrinterStateMessage“: “”, “PrinterName“: “HP_Deskjet_1000_J110_series_USB_CN35719JFF05YD_HPLIP”, “PrinterLocation“: “HP Deskjet 1000 J110 series”, “PrinterInfo“: “HP_Deskjet_1000_J110_series_USB_CN35719JFF05YD_HPLIP”, “DeviceUri“: “hp:\/usb\/Deskjet_1000_J110_series?serial=CN35719JFF05YD”, “PrinterMakeAndModel“: “HP Deskjet 1000 j110 Series, hpcups 3.13.4” } ] }

将该参数恢复成之前错误的格式,看能否打印确认是该参数导致不能打印。

操作过程:

ret= setPrinterDevice(name,device_uri)

ret = setPrinterModel(name,ppd)

enablePrinter()
恢复后(不可可打印)调用GetDestAttrs后返回值如下:
{ “PrinterList”: [ { “PrinterIsAcceptingJobs”: 1, “PrinterIsShared”: 1, “PrinterState”: 5, “PrinterStateMessage”: “\/usr\/lib\/cups\/backend\/hp failed”, “PrinterName”: “HP_Deskjet_1000_J110_series_USB_CN35719JFF05YD_HPLIP”, “PrinterLocation”: “”, “PrinterInfo”: “HP_Deskjet_1000_J110_series_USB_CN35719JFF05YD_HPLIP”, “DeviceUri“: “hp:\\\/usb\\\/Deskjet_1000_J110_series?serial=CN35719JFF05YD”, “PrinterMakeAndModel”: “HP Deskjet 1000 j110 Series, hpcups 3.13.4” } ] }

可见的确是因为该设置参数导致的问题!!!!!!!!

将开发板重置后排除第二次通过CUPS管理界面添加打印机后的影响(暂时不执行)。

GetPPDs接口:

将两个(product,make_model)参数设置成ALL时无法获取到PPD信息,将make_model设置成“HP Deskjet 1000 J110 series”时能获取到PPD信息,但是只有一条信息,如下:

{ “PpdInfo”: [ { “NumPpds”: 0, “PpdDeviceId”: “MFG:HP;MDL:deskjet 1000 j110 series;DES:deskjet 1000 j110 series;”, “PpdNaturalLanguage”: “en”, “PpdMakeAndModel”: “HP Deskjet 1000 j110 Series, hpcups 3.13.4”, “PpdName”: “hp-deskjet_1000_j110_series.ppd.gz” } ] }

 

在设置打印机驱动时使用ppd参数为:PpdName:hp-deskjet_1000_j110_series.ppd.gz

调用SetPrinterModel(PRINTERNAME,PPDNAME)再调用EnablePrinter(PRINTERNAME)即可成功添加打印机。

PPD列表信息格式:PpdMakeAndModel(PpdNaturalLanguage)

HP Deskjet 1000 j110 Series, hpcups 3.13.4en)尝试一下是否能使用这个信息来设置打印机

因为系统里面PPD文件太多,目前已经有4200个,如果一次性获取所有的信息必然导致容器必须定义的够大,很可能还不能装完所有的信息(make_and_mode & ppdname

解决办法:

将获取信息分两步:

第一步:调用GetPPDs获取到Make_model信息,截取打印机品牌:

the make_model Zebra CPCL Label Printer

获取结果如下:

 PpdInfo: [ { “Make”: “Apollo” }, { “Make”: “Apple” }, { “Make”: “Brother” }, { “Make”: “Canon” }, { “Make”: “Citizen” }, { “Make”: “Compaq” }, { “Make”: “DEC” }, { “Make”: “Dai” }, { “Make”: “Dymo” }, { “Make”: “Epson” }, { “Make”: “Fujifilm” }, { “Make”: “Fujitsu” }, { “Make”: “Generic” }, { “Make”: “Gestetner” }, { “Make”: “HP” }, { “Make”: “IBM” }, { “Make”: “Infotec” }, { “Make”: “Intellitech” }, { “Make”: “Kodak” }, { “Make”: “Kyocera” }, { “Make”: “Lanier” }, { “Make”: “Lexmark” }, { “Make”: “Minolta” }, { “Make”: “NEC” }, { “Make”: “NRG” }, { “Make”: “Oki” }, { “Make”: “Olivetti” }, { “Make”: “Olympus” }, { “Make”: “Panasonic” }, { “Make”: “PCPI” }, { “Make”: “Raven” }, { “Make”: “Raw” }, { “Make”: “Ricoh” }, { “Make”: “Samsung” }, { “Make”: “Savin” }, { “Make”: “Seiko” }, { “Make”: “Sharp” }, { “Make”: “Shinko” }, { “Make”: “Sony” }, { “Make”: “Star” }, { “Make”: “Tally” }, { “Make”: “Tektronix” }, { “Make”: “Xerox” }, { “Make”: “Zebra” } ]

 

第二步:然后再根据品牌来获取其具体的PPD文件信息(失败)

如添加HP,获取其打印驱动列表:

修正第二步,为在函数中获取所有的打印机,不过只返回目标品牌的打印机信息。

GetMake(void),返回打印机品牌;

{ “PpdInfo”: [ { “Make”: “Apollo” }, { “Make”: “Apple” }, { “Make”: “Brother” }, { “Make”: “Canon” }, { “Make”: “Citizen” }, { “Make”: “Compaq” }, { “Make”: “DEC” }, { “Make”: “Dai” }, { “Make”: “Dymo” }, { “Make”: “Epson” }, { “Make”: “Fujifilm” }, { “Make”: “Fujitsu” }, { “Make”: “Generic” }, { “Make”: “Gestetner” }, { “Make”: “HP” }, { “Make”: “IBM” }, { “Make”: “Infotec” }, { “Make”: “Intellitech” }, { “Make”: “Kodak” }, { “Make”: “Kyocera” }, { “Make”: “Lanier” }, { “Make”: “Lexmark” }, { “Make”: “Minolta” }, { “Make”: “NEC” }, { “Make”: “NRG” }, { “Make”: “Oki” }, { “Make”: “Olivetti” }, { “Make”: “Olympus” }, { “Make”: “Panasonic” }, { “Make”: “PCPI” }, { “Make”: “Raven” }, { “Make”: “Raw” }, { “Make”: “Ricoh” }, { “Make”: “Samsung” }, { “Make”: “Savin” }, { “Make”: “Seiko” }, { “Make”: “Sharp” }, { “Make”: “Shinko” }, { “Make”: “Sony” }, { “Make”: “Star” }, { “Make”: “Tally” }, { “Make”: “Tektronix” }, { “Make”: “Xerox” }, { “Make”: “Zebra” } ] }

GetPPDs(char * make);返回目标品牌打印机信息[],返回来的PPDnames,如果搜索HP,则有64890个字符,而cgi限制的铲毒为65535字符。

所以,

(1)简单方案:如果需要在界面上直接传递Ppdname那么界面显示出来的字符串也必须是ppdname,这样界面上看起来不怎么人性化,不像CUPS原生界面仅仅显示厂商以及打印机型号。

(2)界面友好方案:而如果要界面上显示厂商和型号,那么界面上就需要调用另一个接口来发送厂商及型号信息给后台让后台去查找目标PPDNAME然后将该信息添加到打印机中。

方案(2)需要确认两点:

1)是通过make_and_mode信息能够获取到目标打印机的ppdname。【经验证——,通过调用局部函数getdestppd(make-and-mode,ppd-name)】

2)界面能够一次性,获取所有目标品牌打印机的make-and-mode信息,并正常显示。【经验证——能】

返回信息:不包含language:

包含language:

 

 

界面调用顺序出错:setprinterdevices setprintermodel enableprinter

getppds传递参数出错:{Brands:””}:,不应该有冒号!

 

打印测试页:

PrintTestPage(printername,/usr/share/cups/data/testprint)

printernameHP_Deskjet_1000_J110_series (HP Deskjet 1000 J110 series)

 

无法打印:

原因分析:

(1)添加打印机时,某项参数没有设定或者没有设定正确

对比Nas项目版本,少了setprinterlocation setprinterinfo两个步骤,

添加上该两个步骤,未见起色。

 

(2)移植组件不完整,比如缺少了某个支持本地打印的组件

对比NAS版本:

command NAS-Net-Printer Puma-Net-Printer 办法【尝试】【确定】
opkg list-installed |grep cups cups – 1.4.4-10 cups – 1.4.4-10
lua-cups – 1.0-10
opkg list-installed |grep ghost ghostscript – 9.06-1 ghostscript – 9.06-3
ghostscript-fonts-std – 8.11-1 #CONFIG_PACKAGE_ghostscript-fonts-std=y
opkg list-installed |grep guten gutenprint – 5.2.9-10 gutenprint-cups – 5.2.9-1
opkg list-installed |grep hplip hplip – 3.13.4-10 hplip – 3.13.4-10
hplip-ppd – 3.13.4-10 去掉:#CONFIG_PACKAGE_hplip-ppd=y

以上表格中使用最后一列的解决方法,重新编译系统进行测试。(10.8.3.47)编译固件:nickli@10.8.3.50:/tftpboot/nickli.img_dbg

结果:系统中少了一些打印机支持,并且通过cups原生界面添加的打印机依然无法打印测试页。

(3)移植gutenprint时,因不同账户编译存在问题,而将Makefile中拷贝cp src/xml/extract-strings /tmp

改成了“cp src/xml/extract-strings ~/”,是否这个改动有问题呢?

 

添加samba打印功能:

当cups打印机组件(cups,ghostscript,gutenprint,hplip)移植成功后,要使用samba共享就很容易了,采用本项目制定的samba版本时,只需要

在/etc/config/samba中增加配置节内容即可,内容如下:

config print

list printer “printer-name”

使用命令形式:

# uci add_list samba.@print[0].printer=”printer-name”

 

测试用的打印机:

HP Deskjet 1000 —–Deskjet J110a series

HP LaserJet p1108

 

认知:

(1)如果只是安装了cups,注意png jpg等图像文件还不能打印,如果需要打印,则要安装ghostScript

通过GS把png等转换为pbm,再打印——>ghostscript还有将图片转化的功能。

结果:在sdk中添加了ghostscript包之后,果然能正常打印jpg,png,pdf文件了。

(2)cups printer 要求每一个客户端手动的配置,进行驱动的安装配置才能正常使用网络打印机:

I can print just fine using p910nd, and CUPS, using the RAW (JetDirect) protocol.  But this requires each client PC to be manually configured.  I’d like the clients to be able to browse for the printer and use the Add Printer Wizard to grab printer drivers.

 

(3)windows端访问cups打印机方法:

1)在Windows下,安装CUPS共享的打印机。可以用samba来共享打印机;

2)我们完全可以使用CUPS的网络打印功能,来完成这一任务。如下图:

添加一台网络打印机并输入URL:http://192.168.1.1:631/printers/HP_Deskjet_1000_J110_series_USB_CN35719JFF05YD_HPLIP,就可以完成打印机添加了,之后的步骤和安装普通的本地打印机一样。其中“192.168.1.2:631/printers”是CUPS打印服务所在地址和端口,“HP_Laser_1020_USB_1”是你的打印机名。
(4)关于samba打印时,samba服务进程对于打印的重要性

如果使用samba打印,那么添加打印机驱动时需要去访问samba服务,以添加samba共享出来的打印机。此时samba进程是开启了的。

 

参考资料:

cups打印管理:

网络打印:

四、附录
1、打印类Classes
在cups 1.1.21之前的版本,需要采用打印类的方式才能提供远程网络打印服务,可以在“Manage Printer Classes”中添加打印类。方法比较简单,建立类后,添加组员打印机即可。但远程连接的URI表示有点不同:
2、远程URI的表示方式,一般有两种:

http://CUPS服务器的IP地址:631/classes/打印机类名

http://CUPS服务器的IP地址:631/printers/打印机名称
请根据不同的情况进行选择。
3、手动安装的cups打印机的一些命令,范例:

/usr/sbin/lpadmin -p LaserJet -E -v parallel:/dev/lp0 -m laserjet.ppd

  1. 添加名为 LaserJet 的打印机 (-p)
    2. 启用要使用的打印机 (-E)
    3. 设置要使用的设备和设备类型 (-v)
    4. 使用驱动程序/PPD 文件 laserjet.ppd (-m)
    字符下打印:

/usr/bin/lp -d LaserJet /etc/aliases
lp 语法将文件 /etc/aliases 打印到 LaserJet 打印机 (-d)。
临时禁用和启动打印机:

/usr/bin/disable -r “Changing Paper” LaserJet
/usr/bin/enable LaserJet
更详细的资料和商业的解决方法,请参考:ESP Print Pro