恩山无线论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1257|回复: 36

Padavan插入HP的GDI打印机时自动发送固件的脚本

  [复制链接]
发表于 2021-8-21 17:18 | 显示全部楼层 |阅读模式
本帖最后由 turboYI 于 2021-8-22 12:51 编辑

我们用无线路由器共享打印机,最容易遇到打印服务开启了,Windows下驱动也按教程正确安装了,但就是打印不正常的问题。我把我的解决办法总结一下,供大家参考。

有些广受欢迎的打印机,如我的HP Laserjet 1020,是所谓的GDI打印机,主要用于Windows系统。这种打印机设计时就简化了固件,ROM里根本没有真正干活的程序。打印机开机之后,必须由计算机把固件传过来安装到内存后,才能正常工作。在Windows系统里,打印机驱动程序就会自动做这个事。Windows支持热插拔技术,就算主机先开机工作,打印机后开机,Windows系统也会识别到USB口接入了打印机,进而发送固件给打印机。打印机在接收到固件后进行启动,这时我们会听到明显的自检轰鸣声。

但GDI打印机一般只提供了Windows下的驱动,将他们连接到Linux主机上并正常工作可不容易。有一些开源项目提供了Linux下的打印机驱动,配合CUPS打印服务器,就能让Debian、Radhat正常打印。最有名的开源项目是foo2zjx,里面的/osx-hotplug/osx-hplj-hotplug.m文件定义了九种HP打印机硬件特征码和对应的固件。阅读源代码,其中的0x03f0, 0x2b17, "/usr/share/foo2zjs/firmware/sihp1020.dl",对应的就是HP Laserjet 1020打印机,它的固件文件名为sihp1020.dl。这些固件可以自己编译生成,也能在网上(http://oleg.wl500g.info/hplj/)下载到现成的。

我们通常只是用Openwrt或Padavan做一个小型的打印服务器。客户机的Windows系统本来就有驱动,所以这里只探索如何在GDI打印机热插入时,作为打印服务器的路由器能识别到打印机并发送固件,让打印机能正常工作。

查资料得知,Padavan用mdev来提供硬件热插拔支持。我用RT-N56U路由器(Padavan版本为3.4.3.9-099_20-10-2),经过不断实验,写了一个SHELL脚本,基本上实现了:
1. 读取设备特征,确定打印机型号,从网上下载对应的固件文件(对应 foo2zjx 里的九种HP打印机)。
2. 开机时发现连接了打印机,就发送固件给打印机。
3. 开机后插入打印机,系统能发现并发送固件给打印机。

把下面代码加入到“在路由器启动后执行”脚本的末尾,保存重启就可以了。
  1. # 准备打印机热插拔时安装固件(从网上下载固件) turboYI 20210821
  2. cat > "/var/usblp_hotplug.sh" <<-\EOF
  3. #!/bin/sh
  4. set -e
  5. HPLJSITE=http://oleg.wl500g.info/hplj
  6. LOGFILE=/var/usblp_hotplug.log
  7. FIRMWARE=
  8. if [ $# -eq 3 ]; then
  9.     #这里用于开机时调用
  10.     DEVNAME=$1
  11.     ACTION=$2
  12.     DEVD=$3/../../..
  13. else
  14.     DEVD=/sys${DEVPATH}/../../..
  15. fi
  16. if [ -f $DEVD/product ]; then
  17.     product=`cat $DEVD/product`
  18.     vid=`cat $DEVD/idVendor`
  19.     pid=`cat $DEVD/idProduct`
  20.     case $vid-$pid in
  21.     03f0-0517)
  22.         FIRMWARE=sihp1000.dl
  23.         ;;
  24.     03f0-1317)
  25.         FIRMWARE=sihp1005.dl
  26.         ;;
  27.     03f0-4117)
  28.         FIRMWARE=sihp1018.dl
  29.         ;;
  30.     03f0-2b17)
  31.         FIRMWARE=sihp1020.dl
  32.         ;;
  33.     03f0-3d17)
  34.         FIRMWARE=sihpP1005.dl
  35.         ;;
  36.     03f0-3e17)
  37.         FIRMWARE=sihpP1006.dl
  38.         ;;
  39.     03f0-4817)
  40.         FIRMWARE=sihpP1005.dl
  41.         ;;
  42.     03f0-4917)
  43.         FIRMWARE=sihpP1006.dl
  44.         ;;
  45.     03f0-3f17)
  46.         FIRMWARE=sihpP1505.dl
  47.         ;;
  48.     esac
  49.     if [ $FIRMWARE ]; then
  50.         if [ ! -f /var/$FIRMWARE ]; then
  51.             curl -o /var/$FIRMWARE $HPLJSITE/$FIRMWARE
  52.         fi
  53.         if [ -c /dev/$DEVNAME -a $ACTION = 'add' ]; then
  54.            echo "$(date "+%Y-%m-%d %H:%M:%S") : Sending $product firmware to $DEVNAME" > $LOGFILE
  55.            cat /var/$FIRMWARE > /dev/$DEVNAME
  56.            echo "$(date "+%Y-%m-%d %H:%M:%S") : done." >> $LOGFILE
  57.         fi
  58.     fi
  59. fi
  60. #调用Padavan原处理程序
  61. if [ $# -eq 2 ]; then
  62.   /sbin/mdev_lp $MDEV $ACTION
  63. fi
  64. EOF
  65. chmod a+x /var/usblp_hotplug.sh
  66. sed -i 's/\/sbin\/mdev_lp/\/var\/usblp_hotplug.sh/' /etc/mdev.conf
  67. # 启动时如果检查到了打印机,就安装固件
  68. if [ -c /dev/usb/lp0 ]; then
  69.     devpath=`find /sys/devices/platform/ehci-platform/ -name 'lp0' | grep 'usb/lp0'`
  70.     if [ $? = 0 ]; then
  71.         /var/usblp_hotplug.sh usb/lp0 add $devpath
  72.     fi
  73. fi
复制代码
论坛的的代码编辑器模块会删除缩进,看起来很不爽,后面放一个源代码图片。脚本文件可以从附件下载,解压后用记事本打开复制代码。脚本运行正确的话,运行 cat /etc/mdev.conf 可以看到里面有 usb/lp[0-9] 0:0 0660 */etc/storage/usblp_hotplug.sh $MDEV $ACTION 这一行。见后面的附图。

本脚本从 http://oleg.wl500g.info/hplj 下载固件文件。我从网上搜索到了这个分享了HP的GDI打印机固件的网站,感谢这个网站的主人为我们提供了方便!





2021-08-21_172618.png
mdev_conf.png

turboYI_mdev_usb_lp.zip

1010 Bytes, 下载次数: 63

Padavan共享HP的GDI打印机时自动发送固件的脚本

我的恩山、我的无线 The best wifi forum is right here.
发表于 2021-8-21 19:34 | 显示全部楼层
我记得之前谁提到过在路由上热插拔后会找不到打印机,然后他写了个脚本每10秒还是多长时间自动检测并连接打印机...

点评

那种办法我原来也用过,但是轮询明显不如事件驱动好。 现在这个脚本是利用linux的mdev的热插拔机制写的,只在系统开机时或插上打印机时调用一次。发送固件给打印机后,打印机会启动自检,因此可以用两个步  详情 回复 发表于 2021-8-21 22:04
我的恩山、我的无线 The best wifi forum is right here.
发表于 2021-8-21 20:20 | 显示全部楼层
谢谢分享!学习学习!
来自安卓客户端来自安卓客户端
我的恩山、我的无线 The best wifi forum is right here.
 楼主| 发表于 2021-8-21 22:04 | 显示全部楼层
邪恶海盗 发表于 2021-8-21 19:34
我记得之前谁提到过在路由上热插拔后会找不到打印机,然后他写了个脚本每10秒还是多长时间自动检测并连接打 ...

    那种办法我原来也用过,但是轮询明显不如事件驱动好。
    现在这个脚本是利用linux的mdev的热插拔机制写的,只在系统开机时或插上打印机时调用一次。发送固件给打印机后,打印机会启动自检,因此可以用两个步骤来测试:
    步骤一:把脚本添加进去后保存重启路由器,如果这时路由器是插了打印机的,启动后能听到打印机的自检声。
    步骤二:从路由器上拔掉打印机USB插头,等几秒再插回去,也会再次听到打印机的自检声。
我的恩山、我的无线 The best wifi forum is right here.
发表于 2021-8-22 00:16 | 显示全部楼层
尝试了好几次,没有成功呢,开机有反应,重新插拔没有反应了

点评

我大致分析一下。 如果路由器开机时能听到打印机自检声,说明生成的 /var/usblp_hotplug.sh 脚本是能正常工作的。 重新拔插USB插头后没有反应,说明系统没有发现设备硬件有改动。这可能是mdev热插拔处理程序没有起  详情 回复 发表于 2021-8-22 10:29
我的恩山、我的无线 The best wifi forum is right here.
 楼主| 发表于 2021-8-22 10:29 | 显示全部楼层
luang4089 发表于 2021-8-22 00:16
尝试了好几次,没有成功呢,开机有反应,重新插拔没有反应了

我大致分析一下。
如果路由器开机时能听到打印机自检声,说明生成的 /var/usblp_hotplug.sh 脚本是能正常工作的。
重新拔插USB插头后没有反应,说明系统没有发现设备硬件有改动。这可能是mdev热插拔处理程序没有起作用,可以查看 /etc/mdev.conf 配置文件,看里面是否有由 /var/usblp_hotplug.sh 脚本接管。
padavan原来 mdev.conf 文件内容如下:
  1. # <device regex> <uid>:<gid> <octal permissions> [<@|$|*> <command>]
  2. sd[a-z] 0:0 0660 */sbin/mdev_sd $MDEV $ACTION
  3. sd[a-z][0-9] 0:0 0660 */sbin/mdev_sd $MDEV $ACTION
  4. usb/lp[0-9] 0:0 0660 */sbin/mdev_lp $MDEV $ACTION
  5. sg[0-9] 0:0 0660 @/sbin/mdev_sg $MDEV $ACTION
  6. sr[0-9] 0:0 0660 @/sbin/mdev_sr $MDEV $ACTION
  7. weth[0-9] 0:0 0660 */sbin/mdev_net $MDEV $ACTION
  8. wwan[0-9] 0:0 0660 */sbin/mdev_net $MDEV $ACTION
  9. cdc-wdm[0-9] 0:0 0660 */sbin/mdev_wdm $MDEV $ACTION
  10. ttyUSB[0-9] 0:0 0660 */sbin/mdev_tty $MDEV $ACTION
  11. ttyACM[0-9] 0:0 0660 */sbin/mdev_tty $MDEV $ACTION
  12. video[0-9] 0:0 0660
  13. null 0:0 0666
  14. zero 0:0 0666
  15. full 0:0 0666
  16. random 0:0 0666
  17. urandom 0:0 0444
复制代码
里面的关键行是
  1. usb/lp[0-9] 0:0 0660 */sbin/mdev_lp $MDEV $ACTION
复制代码

usb/lp[0-9]就是对应USB接口上的打印机设备,对应的热插拔处理程序是 /sbin/mdev_lp。mdev_lp是不能修改的系统文件。
我在1楼的脚本里,用了这样的命令
  1. sed -i 's/\/sbin\/mdev_lp/\/var\/usblp_hotplug.sh/' /etc/mdev.conf
复制代码
把usb/lp的默认处理程序修改成了我写的 /var/usblp_hotplug.sh 脚本,实现了接管——每当系统插入了USB打印机,就会执行。 /var/usblp_hotplug.sh 脚本的用途就是检测打印机型号,下载和发送正确的固件给打印机。
你可以用下面附件图片的的办法查看一下/etc/mdev.conf,是不是有这一行。如果没有,就核对一下`sed `那一句是否正确。插入脚本时,最好是下载附件解压后,用记事本打开turboYI_mdev_usb_lp.sh后复制脚本,避免字符错漏。


还有,脚本能在我的路由器上完美运行,并不能证明它能适应所有。希望试用过的朋友,回复一下路由器型号、Padavan的版本号、打印机型号和运行效果等信息,这才能促进我们来完善它。
mdev_conf.png

点评

hp1018 测试正常,非常感谢  详情 回复 发表于 2021-9-6 15:40
非常感谢,用的最新版本H大固件已经测试成功,我的P1007,03f0-4817对应型号是p1007,自己修改了 另外第一次用可能需要重新启动路由器的打印机服务,可以解决未知不连机问题 我的测试过程中新版本热插拔偶尔不起作  详情 回复 发表于 2021-8-22 15:05
我的恩山、我的无线 The best wifi forum is right here.
发表于 2021-8-22 15:05 | 显示全部楼层
turboYI 发表于 2021-8-22 10:29
我大致分析一下。
如果路由器开机时能听到打印机自检声,说明生成的 /var/usblp_hotplug.sh 脚本是能正 ...

非常感谢,用的最新版本H大固件已经测试成功,我的P1007,03f0-4817对应型号是p1007,自己修改了
另外第一次用可能需要重新启动路由器的打印机服务,可以解决未知不连机问题
我的测试过程中新版本热插拔偶尔不起作用,重启打印机可以自动解决,用时间测试吧,希望有个专用的固件就更好了

点评

其实 P1007和P1005用的是同一个固件,P1008和P1006用的也是同一个固件。开源项目foo2zjx里面的/osx-hotplug/osx-hplj-hotplug.m文件定义了硬件特征码和对应的固件。其中有关代码如下:我又找了个极路由3+Padavan3.4.  详情 回复 发表于 2021-8-22 21:50
我的恩山、我的无线 The best wifi forum is right here.
 楼主| 发表于 2021-8-22 21:50 | 显示全部楼层
luang4089 发表于 2021-8-22 15:05
非常感谢,用的最新版本H大固件已经测试成功,我的P1007,03f0-4817对应型号是p1007,自己修改了
另外第 ...

其实 P1007和P1005用的是同一个固件,P1008和P1006用的也是同一个固件。开源项目foo2zjx里面的/osx-hotplug/osx-hplj-hotplug.m文件定义了硬件特征码和对应的固件。其中有关代码如下:
  1. HOTPLUG HotPlug[] =
  2. {
  3.     0x03f0,        0x0517,                "/usr/share/foo2zjs/firmware/sihp1000.dl",
  4.     0x03f0,        0x1317,                "/usr/share/foo2zjs/firmware/sihp1005.dl",
  5.     0x03f0,        0x4117,                "/usr/share/foo2zjs/firmware/sihp1018.dl",
  6.     0x03f0,        0x2b17,                "/usr/share/foo2zjs/firmware/sihp1020.dl",

  7.     0x03f0,        0x3d17,                "/usr/share/foo2xqx/firmware/sihpP1005.dl",
  8.     0x03f0,        0x3e17,                "/usr/share/foo2xqx/firmware/sihpP1006.dl",
  9.     0x03f0,        0x4817,                "/usr/share/foo2xqx/firmware/sihpP1005.dl",
  10.     0x03f0,        0x4917,                "/usr/share/foo2xqx/firmware/sihpP1006.dl",
  11.     0x03f0,        0x3f17,                "/usr/share/foo2xqx/firmware/sihpP1505.dl",
  12.     0,                0,                NULL,        // Must be last
  13. };
复制代码
我又找了个极路由3+Padavan3.4.3.9-099_21-08-14上试了HP Laserjie 1020,热插拔后能正常发送固件。
也希望又高人能解释有的机型有时会无法热插拔后发送固件的原因,并给出解决办法。如果有稳定的解决办法,就可以推荐老大们做成插件放到固件里了。

点评

请问高手,柯尼卡美能达打印机bizhub185 ,也是GDI打印机,有没有可能?  详情 回复 发表于 2021-8-28 18:12
我的恩山、我的无线 The best wifi forum is right here.
发表于 2021-8-28 18:12 | 显示全部楼层
turboYI 发表于 2021-8-22 21:50
其实 P1007和P1005用的是同一个固件,P1008和P1006用的也是同一个固件。开源项目foo2zjx里面的/osx-hotpl ...

请问高手,柯尼卡美能达打印机bizhub185 ,也是GDI打印机,有没有可能?

点评

没有固件文件,就不好弄。 在foo2zjx项目里,HP的那几个打印机的固件是从官方驱动包里的*.IMG文件里提取的,而柯尼卡美能达的开源驱动不知道有没有人写。 从网上查到的驱动程序包里有KONICA MINOLTA 185-8 和 165-  详情 回复 发表于 2021-8-28 23:52
我的恩山、我的无线 The best wifi forum is right here.
发表于 2021-8-29 22:27 | 显示全部楼层
canon 2900也是GDI打印机不,这个怎么整?

点评

注意打印协议和端口,也许可以直接打印的。我身边没有Canon2900,没有办法实验 GDI打印机并非都是像HP的那几个机器一样需要热加载固件,纯GDI打印机只是要Windows下的GDI驱动程序来渲染图像,这样能省下需要解  详情 回复 发表于 2021-8-30 14:58
我的恩山、我的无线 The best wifi forum is right here.
 楼主| 发表于 2021-8-30 14:58 | 显示全部楼层
panda-soft 发表于 2021-8-29 22:27
canon 2900也是GDI打印机不,这个怎么整?

注意打印协议和端口,也许可以直接打印的。我身边没有Canon2900,没有办法实验

GDI打印机并非都是像HP的那几个机器一样需要热加载固件,纯GDI打印机只是要Windows下的GDI驱动程序来渲染图像,这样能省下需要解析PCL、PostScript等打印语言标准语法的带来的复杂性和存储器开销。
我的恩山、我的无线 The best wifi forum is right here.
发表于 2021-9-5 23:25 | 显示全部楼层
能写个本地的脚本吗?如1020驱动以放在/etc/storage目录里,怕哪天网站挂了

点评

我的路由器只有8M,剩余空间装不下固件,才选择即用即下载。如果空间大,就可以把固件保存下来直接用。在脚本的第50、51、55行修改固件的路径到/etc/storage,保存脚本后,重启路由器。等固件下载完,打印机自检后,  详情 回复 发表于 2021-9-6 14:05
我的恩山、我的无线 The best wifi forum is right here.
 楼主| 发表于 2021-9-6 14:05 | 显示全部楼层
sqbzh 发表于 2021-9-5 23:25
能写个本地的脚本吗?如1020驱动以放在/etc/storage目录里,怕哪天网站挂了

我的路由器只有8M,剩余空间装不下固件,才选择即用即下载。如果空间大,就可以把固件保存下来直接用。在脚本的第50、51、55行修改固件的路径到/etc/storage,保存脚本后,重启路由器。等固件下载完,打印机自检后,进路由器保存一下/etc/storage的内容,以后就不会重复下载了。改好的脚本如下:
  1. # 准备打印机热插拔时安装固件(从网上下载固件) turboYI 20210906
  2. cat > "/var/usblp_hotplug.sh" <<-\EOF
  3. #!/bin/sh
  4. set -e
  5. HPLJSITE=http://oleg.wl500g.info/hplj
  6. LOGFILE=/var/usblp_hotplug.log
  7. FIRMWARE=
  8. if [ $# -eq 3 ]; then
  9.     #这里用于开机时调用
  10.     DEVNAME=$1
  11.     ACTION=$2
  12.     DEVD=$3/../../..
  13. else
  14.     DEVD=/sys${DEVPATH}/../../..
  15. fi
  16. if [ -f $DEVD/product ]; then
  17.     product=`cat $DEVD/product`
  18.     vid=`cat $DEVD/idVendor`
  19.     pid=`cat $DEVD/idProduct`
  20.     case $vid-$pid in
  21.     03f0-0517)
  22.         FIRMWARE=sihp1000.dl
  23.         ;;
  24.     03f0-1317)
  25.         FIRMWARE=sihp1005.dl
  26.         ;;
  27.     03f0-4117)
  28.         FIRMWARE=sihp1018.dl
  29.         ;;
  30.     03f0-2b17)
  31.         FIRMWARE=sihp1020.dl
  32.         ;;
  33.     03f0-3d17)
  34.         FIRMWARE=sihpP1005.dl
  35.         ;;
  36.     03f0-3e17)
  37.         FIRMWARE=sihpP1006.dl
  38.         ;;
  39.     03f0-4817)
  40.         FIRMWARE=sihpP1005.dl
  41.         ;;
  42.     03f0-4917)
  43.         FIRMWARE=sihpP1006.dl
  44.         ;;
  45.     03f0-3f17)
  46.         FIRMWARE=sihpP1505.dl
  47.         ;;
  48.     esac
  49.     if [ $FIRMWARE ]; then
  50.         if [ ! -f /etc/storage/$FIRMWARE ]; then
  51.             curl -o /etc/storage/$FIRMWARE $HPLJSITE/$FIRMWARE
  52.         fi
  53.         if [ -c /dev/$DEVNAME -a $ACTION = 'add' ]; then
  54.            echo "$(date "+%Y-%m-%d %H:%M:%S") : Sending $product firmware to $DEVNAME" > $LOGFILE
  55.            cat /etc/storage/$FIRMWARE > /dev/$DEVNAME
  56.            echo "$(date "+%Y-%m-%d %H:%M:%S") : done." >> $LOGFILE
  57.         fi
  58.     fi
  59. fi
  60. #调用Padavan原处理程序
  61. if [ $# -eq 2 ]; then
  62.   /sbin/mdev_lp $MDEV $ACTION
  63. fi
  64. EOF
  65. chmod a+x /var/usblp_hotplug.sh
  66. sed -i 's/\/sbin\/mdev_lp/\/var\/usblp_hotplug.sh/' /etc/mdev.conf
  67. # 启动时如果检查到了打印机,就安装固件
  68. if [ -c /dev/usb/lp0 ]; then
  69.     devpath=`find /sys/devices/platform/ehci-platform/ -name 'lp0' | grep 'usb/lp0'`
  70.     if [ $? = 0 ]; then
  71.         /var/usblp_hotplug.sh usb/lp0 add $devpath
  72.     fi
  73. fi
复制代码


一般路由器上只会接一台打印机,如果路由器剩余空间很大,而且想以后完全不依赖网络下载固件,可以把7个固件文件全下载保存到/etc/storage/目录里。

点评

如果已经把固件下载到/etc/storage,是不是下面这几句就可以不需要了? if [ ! -f /etc/storage/$FIRMWARE ]; then curl -o /etc/storage/$FIRMWARE $HPLJSITE/$FIRMWARE fi  详情 回复 发表于 2021-9-14 16:05
我的恩山、我的无线 The best wifi forum is right here.
发表于 2021-9-6 15:40 | 显示全部楼层
turboYI 发表于 2021-8-22 10:29
我大致分析一下。
如果路由器开机时能听到打印机自检声,说明生成的 /var/usblp_hotplug.sh 脚本是能正 ...

hp1018 测试正常,非常感谢
我的恩山、我的无线 The best wifi forum is right here.
发表于 2021-9-9 10:34 | 显示全部楼层
路由器设置WIFI打印,打印文件一多系统就卡死,很鸡肋,当然用USB链接到路由器,驱动安装到电脑的没啥意思

点评

卡死是因为打印服务的存储空间不足,并发的任务量又太多。打印任务多的时候,只有等队列前面的打印完毕才能继续打印下一份,如果打印服务的调度程序不完善,就可能出错死掉。 家用无线路由器的配置本来就很低,只能  详情 回复 发表于 2021-9-11 14:26
我的恩山、我的无线 The best wifi forum is right here.
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|Archiver|恩山无线论坛(常州市恩山计算机开发有限公司版权所有) ( 苏ICP备05084872号 )|网站地图

GMT+8, 2021-9-27 14:40

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表