Openwrt添加USB 4G上网、AT指令收发短信

由于希望家里的服务器保持长时间在线,但光猫棒长时间运行时有可能会死机掉线(加装风扇也无济于事)。需要在网络层面第二网络通道实现宽带离线时的远程管理,通过在软路由上加装4G网卡即可通过无线网连接到服务器,同时支持在宽带离线时自动发送告警短信到自己的手机。

设备型号:飞思创EC600N
技术特征:USB Dongle;4G Cat.1;Rndis;AT

注:需要根据自己设备支持的USB驱动协议选择合适的开源驱动。常见与本文相关的 USB 驱动包括: USB 串口驱动(option 和 ACM)和 USBNet 驱动(GobiNet、 QMI_WWAN、MBIM、NCM、RNDIS 和 ECM)

设备连接

在4G模块中插入SIM卡,将4G上网模块连接至软路由,如果做了软路由设备的虚拟化(例如PVE),需要将USB设备挂载到Openwrt的虚拟机中。

设备连上系统后,有可能可以直接用。常见的设备信息查询命令有lsusb(需要安装usbutils)和dmesg

# lsusb
...
Bus 009 Device 002: ID 2c7c:6002 Android Android
Bus 009 Device 001: ID 1d6b:0002 Linux 5.10.176 xhci-hcd xHCI Host Controller
...

# dmesg
...
[   14.747694] usbcore: registered new interface driver usbserial_generic
[   14.748696] usbserial: USB Serial support registered for generic
[   14.749861] usbcore: registered new interface driver cdc_ether
[   14.755247] PPP generic driver version 2.4.2
[   14.759076] NET: Registered protocol family 24
[   14.762695] rndis_host 9-1:1.0 usb0: register 'rndis_host' at usb-0000:07:1b.0-1, RNDIS device, ae:0c:29:a3:9b:6d
[   14.764059] usbcore: registered new interface driver rndis_host
[   14.765991] usbcore: registered new interface driver option
[   14.766985] usbserial: USB Serial support registered for GSM modem (1-port)
[   14.768162] option 9-1:1.2: GSM modem (1-port) converter detected
[   14.769269] usb 9-1: GSM modem (1-port) converter now attached to ttyUSB0
[   14.770379] option 9-1:1.3: GSM modem (1-port) converter detected
[   14.771417] usb 9-1: GSM modem (1-port) converter now attached to ttyUSB1
[   14.772503] option 9-1:1.4: GSM modem (1-port) converter detected
[   14.773562] usb 9-1: GSM modem (1-port) converter now attached to ttyUSB2
[   14.776652] kmodloader: done loading kernel modules from /etc/modules.d/*
...

上网驱动

我的Openwrt内核版本是5.10.176,OpenWrt版本22.03。对于高版本的内核与系统,基于Rndis协议的4G模块是免驱的,但如果是定制版的OpenWrt有概率会阉割相关的USB功能,需要安装以下内核模块。

kmod-usb-net-rndis
(依赖)kmod-usb-net-cdc-ether
(依赖)kmod-usb-net
(依赖)kmod-usb-core

正常识别后可在lsuab命令中看到一个名为Android设备,或者有GSM等信息。同时可查询到设备自动创建的网卡usb0 与自动分配的 Client IP

# lsusb
Bus 009 Device 002: ID 2c7c:6002 Android Android

# ip addr
4: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN qlen 1000
    link/ether ae:0c:29:a3:9b:6d brd ff:ff:ff:ff:ff:ff
    inet 10.3.152.196/8 brd 10.255.255.255 scope global usb0
       valid_lft forever preferred_lft forever
    inet6 fe80::ac0c:29ff:fea3:9b6d/64 scope link
       valid_lft forever preferred_lft forever

如果需要启用这个4G模块并在设备上配置上网,需要先登录OpenWrt。在“网络”->“接口”->“设备”中找到usb0,点击“配置”后保存,保存并应用。(好像也不需要)

之后就可以在常用的接口页面中添加接口,协议使用“DHCP 客户端”,选择“usb0”作为接口设备,按需在“高级设置”中配置“使用默认网关”,防火墙设置中将接口添加到“wan”区,其他使用默认值。

如果不是使用4G模块直接上网,需要取消勾选“使用默认网关”,网络流量不会自动走到这个设备上。如果宽带和4G模块同时配置“使用默认网关”,会存在冲突导致上不了网。之后可以通过wman3或者手动配置路由规则实现“按IP;按设备;按域名”等定向传输方式。

串口通信

一个USB设备上可以存在多个USB接口(指内核传输接口),多个USB接口构成一个USB复合设备,因此可以在不同的接口上加载不同的USB驱动实现不同的功能。不兼容的设备可能需要调整VID、PID和接口号等信息才能实现USB的驱动对齐。

我购买的这款设备在向店家讨要了技术文档和驱动代码(C代码实现)后发现,厂商使用了wwan.h头文件和option.h头文件,因此断定可以直接安装对应的编译好的内核驱动即可。

kmod-usb-serial,kmod-usb-serial-option,kmod-usb-serial-wwan
(依赖)kmod-usb-core

安装完成后重新插拔设备(大概率是需要插拔的,甚至需要重启OpenWrt,触发驱动加载),即可在/dev路径下看到/dev/ttyUSB0;/dev/ttyUSB1;/dev/ttyUSB2等设备。

根据厂商提供的技术文档,可以找到AT指令串口对应的端口号。

使用 minicom 即可通过USB转串口调试4G模块上的AT控制器。如果自己编程则可以实现短信的自动收发。至于发送中文短信问题,目前只知道可以使用UCS2编码的十六进制字符发送。

AT+CMGF=1
AT+CSCS=UCS2
AT+CSMP=17,167,0,8
AT+CMGS=12311112222
>4F60597D   //你好的UCS2编码的十六进制字符串
[ctrl+z]   // 发送短信
+CMGS: 1

问题排查

根据厂商的技术文档,记录一下如何在系统内核中找到USB设备运行的状态和日志。

可通过检查/sys/bus/usb/drivers 的目录确认是否存在 USB 驱动程序。

# ll /sys/bus/usb/drivers
drwxr-xr-x   11 root     root             0 Mar 11 11:40 ./
drwxr-xr-x    4 root     root             0 Mar 10 23:02 ../
drwxr-xr-x    2 root     root             0 Mar 11 11:40 cdc_ether/
drwxr-xr-x    2 root     root             0 Mar 11 11:40 hub/
drwxr-xr-x    2 root     root             0 Mar 11 11:40 option/
drwxr-xr-x    2 root     root             0 Mar 11 11:40 rndis_host/
drwxr-xr-x    2 root     root             0 Mar 11 11:40 usb/
drwxr-xr-x    2 root     root             0 Mar 11 11:40 usb-storage/
drwxr-xr-x    2 root     root             0 Mar 11 11:40 usbfs/
drwxr-xr-x    2 root     root             0 Mar 11 11:40 usbhid/
drwxr-xr-x    2 root     root             0 Mar 11 11:40 usbserial_generic/

通过命令查询设备列表:cat /sys/kernel/debug/usb/devices,如果设备驱动未识别设备,这里的Driver=之后会显示<nil>

T:  Bus=09 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=2c7c ProdID=6002 Rev= 3.18
S:  Manufacturer=Android
S:  Product=Android
S:  SerialNumber=0000
C:* #Ifs= 5 Cfg#= 1 Atr=c0 MxPwr=500mA
A:  FirstIf#= 0 IfCount= 2 Cls=e0(wlcon) Sub=01 Prot=03
I:* If#= 0 Alt= 0 #EPs= 1 Cls=e0(wlcon) Sub=01 Prot=03 Driver=rndis_host
E:  Ad=87(I) Atr=03(Int.) MxPS=  64 Ivl=4096ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host
E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0c(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
E:  Ad=89(I) Atr=03(Int.) MxPS=  64 Ivl=4096ms
E:  Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
E:  Ad=88(I) Atr=03(Int.) MxPS=  64 Ivl=4096ms
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

You may also like...

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注