早在6年前,我就在家里的树莓派上搭建了一个属于自己的接码平台,但是进入2025年以后,这个接码平台接收的延迟越来越大,到最后甚至已经无法接收到短信,而当我把卡去取下来插到我的手机上后才发现,2G/3G已经退网了,是时候该把接码平台升级到4G了。

购买4G网卡

六年间,虽然我的接码平台从树莓派升级到PVE的虚拟机,性能强了好几倍,接码平台的细节调整了好几次,但是我的网卡还是那个华为的E173,这是一个WCDMA的网卡,现在2G3G已经退网,我必须选一个支持4G的网卡了。
在2025年要去选择一款支持4G的网卡真的挺难了,因为我没有使用开发板,那么IOT上的一些4G模块没法使用,而一些PCIE设备我又没法去搞SIM卡底座,于是USB接口的4G网卡成了我唯一的选择。但是USB的4G网卡可太难找了,随着现在移动端设备的普及,USB的网卡基本上很难有新品了,闲鱼上要么搜出来的都是4G网络的随身Wi-Fi,要么就是Gammu数据库里不支持的设备。最后我选择了华为的E3276,这款网卡在Gammu的数据里标记支持短信,但是其他支持一个都没有,而我了解到这个网卡甚至分成了中国版和海外版本,且海外版本存在多个版本。因为我接码的卡在中国大陆使用中国移动的信号,于是最后我在闲鱼花50元购买一款全新未拆封的中国移动定制版的华为E3276,到手拆封才发现这是个2013年出4G网卡,已经存放了12年了,幸运的是产品是好的。这张网卡支持TDD-LTE和FDD-LTE,满足我的需求。

系统部署

把USB网卡插上后,真就是一步一个坑。

模式切换

插上网口后,我使用lsusb想看看设备的情况,系统输出

1
2
3
# 查看USB设备
~ $ lsusb
Bus 001 Device 016: ID XXXX:YYYY Huawei Technologies Co., Ltd. Modem (Mass Storage Mode)

我的USB网卡使用的是存储模式,这个其实很正常,一般网卡这种产品插入Windows后识别成存储设备方便用户去安装驱动,这一两年无论是Windows 10和Windows 11都自带了大量的兼容驱动用户体验无感很多,但是这是一个12年前的产品,那个时候大量的用户还是使用着Windows 7,于是第一步我需要把他从存储设备改成Modem (写到这的时候我思考了半天Modem的中文是啥,调制解调器,二十多年没听过的名字了),修改模式需要使用usb_modeswitch,使用的方法为sudo usb_modeswitch -v VID -p PID,其中VIDPID需要根据自己设备来修改,切换后VIDPID会可能发生变化。

1
2
~ $ lsusb
Bus 001 Device 020: ID XXXX:ZZZZ Huawei Technologies Co., Ltd. Modem/Networkcard

可以看到切换后我的设备的PID发生了变化,设备后面也明确标记出当前的状态。/dev/目录下也出现了多个ttyUSB*设备。
但是如果USB设备发生断开重新连上后,它又会回到存储模式,因此我们需要在udev中去修改它的模式。
首先需要创建一个规则,路径在/etc/udev/rules.d/里,注意udev是存在优先级关系的,你可以在互联网上找到udev的使用说明。
我们需要在udev的规则里增加这样一段:

1
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="XXXX", ATTRS{idProduct}=="YYYY", RUN+="/usr/sbin/usb_modeswitch -v XXXX -p YYYY -M 'YOURMESSAGECONTENT'"

其中XXXX为你设备的VID,YYYY为存储模式下PID,ZZZZ为切换为网卡模式后的PID,-M的内容为你网卡的messageContent,这个信息建议你在互联网使用设备存储模式下的VIDPID去搜寻。
修改好规则后使用sudo udevadm control --reload-rules来使规则生效。

让接码平台持久化

设备别名

上面我们使用udev让设备常驻为了网卡模式,这六年来我的接码平台遇到过USB断开重连导致ttyUSB*发生变化情况,于是我们还可以使用udev来给网卡别名以方便Gammu的配置文件里固定设备名。
还是一样的编辑udev的规则,添加这样一行。

1
KERNEL=="ttyUSB*", ATTRS{idVendor}=="XXXX", ATTRS{idProduct}=="ZZZZ", MODE:="0777", SYMLINK+="YOURALIAS"

这里的VIDPID需使用设备在网卡模式下的VIDPIDSYMLINK为你自定义的别名。
到这一步后我们就可以在Gammu-smsd的配置文件中固定我们的设备名了。

给Service增加Timer

我以前就给Gammu-smsd增加了Service,但是这六年来,服务会因信号等各种原因报错失效,于是我们可以增加Timer来让自动重启来保障SLA,路径为/usr/lib/systemd/system

1
2
3
4
5
6
7
8
9
[Unit]
Description=gammu-smsd timer

[Timer]
Unit=gammu-smsd.service
OnUnitActiveSec=30min

[Install]
WantedBy=timers.target

配置分享

记录分享下我的现在的Gammu-smsd和转发Telegram-bot的配置与脚本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# Configuration file for Gammu SMS Daemon

# Gammu library configuration, see gammurc(5)
[gammu]
# Please configure this!
# 请根据自己的实际情况修改配置
port = /dev/USB-TDDLTE
connection = at19200
# Debugging
#logformat = textall

# SMSD configuration, see gammu-smsdrc(5)
[smsd]
# 收到短信后的执行的脚本
RunOnReceive=/root/receive-sms.sh
# 日志存储
service = files
logfile = /var/log/gammu/gammu-smsd-$1.log
# Increase for debugging information
debuglevel = 0

CheckSecurity = 0

# Paths where messages are stored
inboxpath = /var/spool/gammu/inbox/
outboxpath = /var/spool/gammu/outbox/
sentsmspath = /var/spool/gammu/sent/
errorsmspath = /var/spool/gammu/error/

# 多段短信超时时间(系统默认是600s)
MultipartTimeout=5

相对六年前,增加了日志的存储和修改了长短信的分段超时时间。

1
2
3
4
5
6
7
8
9
# 短信转发Telegram脚本
TOKEN="YOUR-TELEGRAM-BOT-TOKEN"
CHAT_ID=YOUR-TELEGRAM-CHAT-ID
URL="https://api.telegram.org/bot$TOKEN/sendMessage"
DATE=`date +'%Y/%m/%d %H:%M:%S'`
for i in `seq $SMS_MESSAGES` ; do
#eval "curl -s -X POST $URL -d chat_id=$CHAT_ID -d text=\"\${SMS_${i}_TEXT}\""
eval "curl -s -X POST $URL -d chat_id=$CHAT_ID -d text=\"\${SMS_${i}_NUMBER}: \$DATE %0A=============================%0A\${SMS_${i}_TEXT}\""
done

相对六年前,增加发信人的显示,增加了接收到短信的时间,如果需要查看短信发送的日期时间请前往/var/spool/gammu/inbox/查看文件名。