吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 16672|回复: 102
收起左侧

[系统底层] ”打印服务器 “原理探究,USB驱动开发和验证

    [复制链接]
JuncoJet 发表于 2021-3-16 16:57
无奈,想不出好的标题,为了和板块贴合,只能又臭又长了

[section .前言]
前不久财务买了个打印机,然后呢,又不想在自己电脑上进行共享(要求贼高),怕电脑卡。然你呢,把这需求和供应商说了,然后给搞来了一个叫“打印服务器”的神器。
这小东西把USB打印机插上面,不需要给打印服务器装驱动(驱动是安装自己电脑上,这个和普通的网络打印机一样),就能够实现网络打印了。反正我认为很有意思,猜测这东西可能和串口服务器一样,只是单纯转发,而并不需要提供复杂的服务。
未标题-1.jpg (图片已打码,仅做拓扑图展示)
像普通的打印机共享,基本都是基于一定的协议的。比如samba协议,就常见的Windows共享协议,创建共享打印机进网上邻居双击安装打印机就可以使用了。还有是http共享打印机,这个是cups可以创建的共享打印机,可以通过一个http的url链接进行打印,并且支持使用代{过}{滤}理服务器。
而9100端口,常见于本身就是网络打印机的打印机,公司里十分常见。支持postscript等脚本,通过9100发送给打印机后,打印机就能打印出来。原理简单,稳定,成本低廉,有比较多的优势,所以被广泛的使用。
USB打印机转成9100的网络打印机,在Linux上应该是比较容易实现的,因为有一群大神开发了cups这牛物。但如果考虑移植性和轻便,以及乐趣,自然是要自己实现才比较有意思。

[section .正文]
作为一只“栈溢出工程师”,凡事讲究亲力亲为是我们的准则。
对于设计验证和实现,首先考虑验证程序简单,并且能够实现跨平台。首选qt,libusb本身是个C库,提供的是C的头文件,所以选用C/C++写会避免不少麻烦。然后qt能够实现不同系统上包括UI和网络代码的一致性。
关于libusb,他是一个比较有名的跨平台USB库,这套库支持win、linux、mac os、bsd等操作系统。知名的开源开发环境Arduino就是通过libusb库来实现atmage32u4这种mcu下载程序的。
但,libusb有分两个主流的版本,一个是libusb-0.1(简写为libusb0,Arduino使用的就是0.1版本的库)还有个是libusb-1.0(Linux2.6之后的版本基本上都只用1.0了,并且包管理器里0.1的devel版本已经不包含头文件了。mac os x中brew可以安装的是1.0.22版本,freebsd也是提供的1.0版本)。可见1.0版本已是主流,考虑兼容性的话个人建议使用1.0版本。
Windows上移植的libusb,libusb-win32是0.1的,另外还有WinUSB(libusb),来自github官方版本,可以详见https://github.com/libusb/libusb/wiki/Windows,也可以看一下zadig(https://zadig.akeo.ie/)这个软件上面提供的介绍。这软件安装USB驱动非常方便,并且开源了他的核心代码,为作者点赞。

[section .验证]
验证1,先写一个USB版的HelloWorld,由于第一次写USB程序,先从简单的开始。
列出VID&PID,USB设备的核心应该就是这个了,当一个不明物体插进USB后,首先系统会获取这个VID和PID,并且自动的搜索驱动。VID(idVendor)是主要识别生产厂商的,PID(idProduct)则是负责识别产品。
这两个东西在一起组成了,USB的唯一ID,重名的几率非常的低。因为同一家厂商是不会做出PID相同的东西的。
Image 740.jpg

其次需要知道的东西是interface(MI,Muti-Interface?),还有endpoint。下面程序是列出打印机的interface和endpoint,操作读写USB设备时,必不可少的参数。
Image 741.jpg

验证2,使用 "nc -l -p 9100>文件" 命令把打印机驱动发送给打印机的数据给保存下来。然后尝试直接把这个数据给发送到USB端口。
Image 745.jpg
Image 747.jpg

验证3,使用qt创建一个监听9100端口的服务器,将读取到的数据,发送到USB端口。
Image 746.jpg
微信图片_20210316164752.jpg

[section .后续]
后续最想做的就是想用esp32-s2来重新实现这么个功能,虽然esp32的RAM不大,但优化的好的话,应该是能实现打印服务器的。s2版本的话支持IP协议栈和USB OTG(USB HOST和USB DEVICE),可行性还是很高的,并且成本可能只需要20-30元。
使用MTK的OpenWrt之类的软路由,或者全志的开发板也能实现,但是毕竟价位不低。并且有现成套件,移植意义不是很大。
另外就是这种打印转发在连续打印时会有点小问题,需要实现队列或者缓冲池,然后适的重新对包进行切片。
根据抓包可以看出,PJL命令(我手头这台是HP的打印机,别的打印机可能会使用不同的命令)比较多,有固定的切片长度。但是通过网络发送的话PJL命令是连续的,所以实现对命令的重切片是非常有必要。
Image 743.jpg

[section .感言]
USB真的是很棒的东西呢,记得小时候家里的电脑只有PS2接口和软驱(黄金奔腾PRO 200MHz),还尝试过PS2转USB来插入奇怪的东西,显然只能使用键盘鼠标。
曾经的美好时光依旧是记忆如新,下次来尝试一下PS2接口设备?

免费评分

参与人数 25吾爱币 +24 热心值 +18 收起 理由
maoxinwang + 1 用心讨论,共获提升!
tyui + 1 + 1 我很赞同!
5omggx + 1 + 1 用心讨论,共获提升!
gzshlp + 1 我很赞同!
suntao2002 + 1 厉害
liu101816 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
锋范fast + 1 + 1 用心讨论,共获提升!
jeehom + 1 + 1 谢谢@Thanks!
吴书醉 + 1 用心讨论,共获提升!
zyxm2013 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
xunuo99 + 1 用心讨论,共获提升!
zhouqhui + 1 我很赞同!
zhangfan_89 + 1 + 1 厉害了,牛人!
featmellwo + 2 + 1 学到了!!!
blindcat + 1 + 1 厉害,向大佬学习
zoro8 + 1 + 1 谢谢@Thanks!
fengyingchun + 1 + 1 小米路由器3可以接打印机无线打印不?
YAO21 + 1 我也就能感叹一下,厉害
qimengNB + 1 + 1 我很赞同!
ww18178 + 1 用心讨论,共获提升!
hsanren + 1 + 1 牛人啊
min_x91 + 1 + 1 我很赞同!
pwp + 1 看完这篇文章,想起6年前注册论坛的目的:打狗。这神奇是不是可以打狗啊?
领悟者的涂鸦笔 + 1 我想个打印机都能卡的电脑还办什么公啊
紫轩冰凌 + 3 + 1 不错 最近也在了解这个

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

msold5 发表于 2021-3-16 20:59
本帖最后由 msold5 于 2021-3-16 21:22 编辑
JuncoJet 发表于 2021-3-16 18:50
Openwrt可以直接cups,自带打印服务器的
所以不需要移植

我是指你“后续”里想用ESP来弄,之前没听说过ESP32可以上Openwrt,所以认为复杂的东西ESP32搞不定。
看上去你对USB非常了解了,刚好有个想法请教一下,不知能否赐教:
起因:因为做计算机维护有时会在远程帮别人弄东西,为了可以随意重启、分区等操作,想做个远程维护硬件
实践:想当然地用Arduino模拟USB键盘鼠标+路由器+摄像头弄了个远程维护器,发现延时太大
现实:外置硬件会给大家带来不方便,即使租借、共享、商家暂放等都不是很方便,当然价格再降些也许有机会,如果一整套ESP32+高清摄像头带USB线卖价能15元内搞定那是另一回事。
设想:本来手机就集成有所有的USB、摄像头、计算、联网、存储等功能,如果能使用APP调用底层USB功能模拟USB键盘、鼠标、模拟U盘,就只需接一根USB线远程帮任何人弄电脑了
扩展:不断完善这个手机APP,同步开始运营网站,并从网络认证一批远程维护精英,可以从此开创一番事业..........
问题:估计安卓和苹果对USB是有制约的,不知道手机是否能以纯软件方式来突破这些制约来驱动USB模拟键盘鼠标?
plauger 发表于 2021-3-17 01:35
本帖最后由 plauger 于 2021-3-17 01:38 编辑

其实还有一个方案也很好用,了解一下virtualhere,也就是共享USB的方案,个人觉得比CUPS更稳定可靠。以前在路由器上刷openwrt玩CPUS,不光能共享,连airprint都弄好了,但有一个BUG始终解决不了,那就是在在使用无线打印时,大概率会在开始一行出现一串乱码,各种编译换版本打补丁都没能解决,只能放弃。现在是openwrt上跑virtualhere服务端,所有电脑上跑virtualhere客户端,实现无线打印一点问题没有,当然airprint是不要想了,这玩艺儿不是打印服务。
____________ 发表于 2021-3-16 17:04
谢谢分享。正好这几天学JAVA的串口,希望多出些串口的教材!
邪恶海盗 发表于 2021-3-16 17:08
就这个还用找供应商么,大多数带USB接口的路由器刷个第三方固件比如OP都能实现,十多年前就有这么玩的了...
吾爱蛋蛋 发表于 2021-3-16 17:10
什么玩意儿看不懂锕
ciker_li 发表于 2021-3-16 17:24
学习学习
coolcalf 发表于 2021-3-16 17:26
可不可以纯软件实现呢?
amarjan 发表于 2021-3-16 17:29
虽然我看不懂,但看起来是个不错的玩意儿
202103132020 发表于 2021-3-16 17:31
hp有部分打印机特别坑人:为了节省成本,机器内根本没有固件!
msold5 发表于 2021-3-16 17:36
ESP32不能上OpenWrt吧?感觉要用树莓派一类的东西来弄才行。自己写协议难度比较高,Linux下应该简单很多。
52changew 发表于 2021-3-16 17:41
看看; 大佬厉害; 详细; 谢谢分享!!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-21 19:43

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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