PID:85821610

在openwrt部署了VirtualHere服务端来共享扫描仪,在使用的过程中发现了一些问题:VirtualHere与USB打印服务器“冲突”。
我在openwrt部署了USB打印服务器,通过p910nd来实现,另外也部署了VirtualHere用于共享打印机的扫描仪,现在遇到的情况是,启用了VirtualHere服务端后,openwrt系统无法识别到打印机,导致打印服务器无法使用,共享打印无法正常进行。对此我Google了一些中文资料,发现并没有人解决了这个问题。这个问题并非我第一个发现,早在19年10月恩山论坛用户就提出过这个问题,但直到现在仍没有人提供解决方法。查看了VirtualHere的官方文档后,我找到了解决办法。很简单,官方提供了能够解决这一问题的功能,只是这个功能在openwrt系统上默认被关闭了。下面来看一下VirtualHere的配置文件,英文水平有限,所有描述均由谷歌翻译而来。

关于config.ini配置文件

所有 VirtualHere USB 服务器设置都存储在一个名为config.ini 的文本文件中,通常与 vhusbd 二进制文件位于同一目录中。
当作为守护程序或服务运行时,config.ini文件可能在 Linux 的 /root 或 Windows 的 c:windowssystem32 中。
当服务器最初启动时,或在没有 config.ini 文件的情况下启动时,它将使用合理的默认值,任何非默认值都将写入新的 config.ini。

关于config.ini配置的参数

所述的config.ini文件具有以下参数(它们不区分大小写),所述参数被输入到一个所述的 config.ininame=value 格式,每行一个。

以下是可选的参数:

ServerName 出现在客户端中的服务器名称,例如“Virtual USB Hub”。如果将此值设置为特殊字符串$HOSTNAME$,它将采用服务器的主机名值。

License服务器的许可证代码。注册服务器时,VirtualHere 通过电子邮件发送此值。

DeviceNicknames这是格式,例如,如果设备插入相同的端口,地址总是相同的。您应该使用 VirtualHere 客户端通过右键单击设备并选择“重命名...”来设置昵称,而不是直接编辑此值,因为在连接客户端之前无法访问该地址。

UseAVAHI 1表示使用Bonjour在网络上广播此服务器的存在,0表示不使用广播消息在网络上宣传此服务器。默认为1开启。关闭此设置对于防火墙后面的客户端很有用,因为防火墙或子网会阻止 IP 广播数据包,他们宁愿直接在客户端中输入 IP 地址。

Hostname这指定了与客户端通信时服务器的主机名。默认情况下,它是调用主机上的主机名实用程序的结果,但可以通过在此处指定一个值来覆盖。例如。USB服务器。请注意,如果网络上有多个 virtualhere 服务器,它们必须具有唯一的主机名

CompressionLimit一旦 USB 传输大于此处指定的字节数,它将被压缩以节省网络传输时间。较小的值将使用更多的 CPU 来略微提高网络吞吐量,较大的值将使用较少的 CPU,但网络吞吐量会受到影响。从反复试验来看384似乎是正确的。

IgnoredDevices这指定了插入服务器时要忽略的设备。此设置的格式xxxx[/yyyy],xxxx/yyyy,...,其中XXXX是设备的USB厂商ID和YYYY是设备的USB产品ID(可选)(没有前导零和值均为十六进制)。例如,在 Raspberry PI 上运行的 VirtualHere 会自动填充它,424/ec00因为这是内置于电路板中的基于 Raspberry Pi USB 的内部以太网适配器,不应共享。要找出特定设备的供应商/产品 ID,请将其插入并从 VirtualHere 客户端查看设备属性。您还可以为产品 ID 指定通配符,例如 424/*

IgnoredBuses(仅限 Linux)这指定要忽略的特定 USB 端口。它的格式hostcontroller-hub.port,hostcontroller-hub.port,...例如忽略连接到 Raspberry pi 上的端口 2 的设备,将此值设置为1-1.2

AllowedDevices除此处列出的设备外,所有设备都将被忽略。它与IgnoredDevices设置相反。格式与IgnoredDevices设置相同,即xxxx[/yyyy][,xxxx/yyyy,]...(无前导零)。如果此值为空,则将允许所有设备(同时考虑上面的IgnoredBuses和IgnoreDevices设置)您还可以为产品 ID 指定通配符,例如 424/*

AutoAttachToKernel将此设置1为允许设备在远程用户不使用设备时可供主机使用。默认适用1于 NAS、Android 和 Debian(64/32 位)以及0所有其他平台

ClaimPorts(仅限 Linux)默认情况下这是0(关闭)。当设置为1virtualhere 服务器时,将阻止服务器内核与设备交互。将此值设置为 1 可使服务器与对其选择的配置 1 敏感的 USB 设备更兼容。当这个设置打开时,内核与设备的唯一交互是查询设备描述符,但是目前外部集线器不能在这个设置打开的情况下使用。

PingInterval默认值为4秒。这是从服务器到客户端的 ping 消息之间的秒数。客户端需要使用PingTimeout响应(见下文),然后才会考虑丢弃套接字并清理连接。有时,如果网络连接不稳定,套接字可能会断开,并且此设置和以下设置有助于针对不稳定连接调整服务器,但是您几乎应该始终将这些设置保留为默认值。

PingTimeout默认值为9秒。如果服务器在此时间之后没有收到来自客户端的响应 ping,则认为连接已断开并已清除。

ControlTimeout默认值为3秒。如果设备表现不佳(由于某种原因卡住),则此设置会检测到并在此时间内向客户端返回错误,而不是无限期地等待...

UseAvahiServiceFile(仅限 Linux)如果设置为1,VirtualHere 服务器将向 Linux 操作系统上的内置 avahi-daemon 注册自己。默认是0这意味着 VirtualHere 服务器将使用其内置的小型 avahi 类型服务器 (mdns)

ReverseClients(新,如果您升级到(至少)服务器 2.4.5 和客户端 3.1.1,则可以直接在 GUI 或客户端 API 中进行配置,无需手动编辑服务器配置文件),此设置将使服务器启动到客户端的连接,而不是客户端启动连接的通常方式。这对于防火墙或 NAT 后面的服务器很有用。指定每个客户端的主机 ip 和可选端口,以逗号分隔。例如ReverseClients=192.168.2.129,192.168.2.110。如果未指定端口,则默认为 7573,这是标准的 virtualhere 反向查找端口。在客户端中,确保在右键单击 USB 集线器 -> 指定集线器 -> 防火墙/NAT下选中启用反向连接。服务器将尝试依次连接到每个客户端。

ReverseClientsRetryPeriod默认为 15 秒。这是服务器尝试反向客户端的连接尝试之间的秒数(它还没有连接到)。

以下是高级参数,因此仅在购买的服务器上支持

TCPPort这是 VirtualHere 服务器运行的 TCP 端口,如果未指定,则默认为7575. 您可以指定任何未使用的端口号,也可以使用 0 指定随机端口。(客户端仍然可以通过 bonjour 广播自动自动查找服务器)。

ClientIdMap此设置允许您将客户端 ID重新映射到昵称。甲客户端ID是当在客户机的日志,它是由在客户机OS确定在自动传递和具有格式 <空间>(<用户名>)。例如,如果客户的用户名为“Michael Jones (michael)”,您可以将客户 ID 更改为“Mick”,那么这将出现在其他客户的使用信息中。这种设置格式是ClientIdMap=,[,,...]例如ClientIdMap=Michael Jones (michael),Mick,Steve Jones (steve),Steve. 客户端 ID 必须与客户端的用户名和全名完全匹配。这可以通过右键单击使用中的设备并查看属性中的 USER: 条目来找到。

HideClientInfo默认值为0(false)。如果设置为1Device In-Use 信息不会显示给其他客户端

NetworkInterface( Linux Only ) 这指定将服务器绑定到哪个网络接口。如果未指定(默认),则服务器将侦听所有网络接口上的传入客户端连接。否则,如果您有多个网卡并且只想侦听其中一个,请指定将服务器绑定到的 IP 地址。

ClientAuthorization这指定了要运行以授权特定用户/设备组合的脚本。

ClientDeauthorization与ClientAuthorization相同,除了在用户与设备断开连接时调用

SSLCert用于 SSL 传输的 ssl PEM 证书文件(包含未加密的公钥和私钥)的完整路径。如果指定了此参数,则与服务器的所有通信都将通过 SSL 而不是普通 TCP 运行。端口将在下面的 sslPort 设置中指定。有关 SSL 的更多信息,请参见此处

SSLPort如果指定了sslCert参数,则此端口将用于客户端通信。端口默认为7574

SSLUseClientCerts将此参数设置1为打开客户端 SSL 证书。如果启用,VirtualHere 客户端必须在连接时向服务器提供 SSL 客户端证书

SSLCAFile此文件包含使用服务器和客户端 SSL 证书的 PEM 编码证书颁发机构 (CA) 可信根证书。

VirtualHere 服务器还包含一个事件处理系统,可以将其配置为在特定时间调用脚本。这对于解决设备怪癖或执行特定操作(如日志记录)很有用,请参见 此处

{mtitle title=end/}

针对前述的问题,我们需要关注的是AutoAttachToKernel这个参数,这个参数决定了USB设备没有在被远程客户端时,能否被服务端主机使用。很显然,根据文档的描述,这项功能在NAS、Android 和 Debian平台默认是开启的,所以很不意外的,在openwrt系统开启VirtualHere后,系统的USB设备就不能再被主机自己使用。
解决方法很简单,那就是编写一个配置文件,将这个功能设置为开启就好了,下面来介绍如何解决。

创建config.ini配置文件

在不同的系统环境中,config.ini可能不会自动创建,我们需要手动来创建一个config.ini文件,在config.ini文件中写入以下参数:

AutoAttachToKernel=1

然后保存文件。前述的各项参数,不必全部写入config.ini配置文件,缺省项目会自动使用系统默认配置,只需写入需要修改的项即可。

附加config.ini启动VirtualHere

将config.ini保存到与VirtualHere程序相同的目录,输入以下命令启动VirtualHere,注意修改文件所在的路径。

/etc/VirtualHere/vhusbdx -b -c /etc/VirtualHere/config.ini

做完这些工作后,问题就解决了,现在USB设备没有被远程使用时,主机自身也可以使用。

VirtualHere常用命令

usage: vhusbdx [-bhliqnu] [-c <configuration file>] [-r <log file>]

options:
   -b run as daemon in the background  作为守护程序运行在后台
   -c configuration file  加载配置启动
   -h display this usage  帮助
   -l display license text 许可证信息
   -i prefer ipv6 (dual/stack) 使用IPV6网络
   -r log to file instead of syslog 输出日志文件