用上网卡转发短信

在 V 站上上了个 SIM 卡的车。但长时间带着俩手机不方便。于是就想办法将短信和电话从备用手机实时转到主力机上。试了 IFTTT,不稳定。然后就想用树莓+SMS 开发版来做这个事儿。偶然间发现其实上网卡里面也藏着短信功能,就买了个上网卡开始鼓捣。

25 块钱,深水鱼二手,包邮到家。

物理

我买来的是华为 E303s。一个 12 年左右的 3G 上网卡,可以插一个大 SIM 卡和一个 MicroSD 卡。

插上 Win 电脑,会识别出来一个 USB 光盘。自动安装驱动,弹出 192.168.1.1 的控制页面。赶快取消自动拨号、断线重连、漫游。反正是把能关的都关了。信号选自动。

插上 Linux 电脑,毛事情都没发生?

  • lsusb 看一下,发现一个 Bus 001 Device 011: ID 12d1:14db Huawei Technologies Co., Ltd.。注意这里的 12d1:14db。后面会用到。
  • dmesg 可以看到,识别了一个 USB Mass Storage,还有一个网卡设备。
  • ip a 可以看到,多了一个网卡。
  • ls /dev | grep ttyUSB,什么都没有。

查资料(都是些 13 年左右的帖子……好老了……毕竟买的是 3G 上网卡,也都是 12、13 年的东西了)发现,它有好多工作模式:一种是 U 盘模式,一种是 HiLink 模式,一种是 Debug 模式,最后还有个序列设备模式。下面我们用两种方法来用它。

方法一 使用内置 WebAPI

这个 3G 上网卡里面有一套 WebUI 给用户使用的。由于是前后端分离的写法,API 可以比较容易地找到,一个 Chrome F12 就可以找出来大多数 API。我们可以用找到的这些 API 来做一些事情,比如状态监测、短信收发。

说简单也简单,说难也难,毕竟是第一次在完全没有文档和说明的情况下扒 API 来用。另外是测试比较费钱……

说一下几个坑的点:

  • 最最关键的,会多出一块网卡。后果是访问某些网站的时候会被带到上网卡的 WebUI 上,而不是从树莓派的有线网链接到 Internet。虽然代码很方便,但不太推荐。
  • 首先是,它是通过 XML 交互的,但也不完全。
  • 其次是,所有参数都是有顺序的,只能用 OrderedDict 进行序列化。
  • 最后是,不需要找着网上的教程去拿 Header、拿 Token、登录。直接暴力 request 解决问题即可。

大体思路是这样的:

  1. 看一下统计信息,如果有未读信息,就处理
  2. 从收件箱里面取出短信
  3. 对于每一条短信,该转发就转发,该 Push 就 Push
  4. 删除这条消息
  5. 收尾,清空发件箱

在用函数调试通过之后,封装成了类,便于使用。整个文件是这样子的

除了没写注释之外,代码风格还算过得去吧?

加入 crontab 豪华套餐,给手机卡充好值,开始享受「双卡」吧。

方法二 使用 AT 指令

这种方式,我们可以用比较低层的命令直接操控。好处是不会因为多一个网卡而出现很多奇奇怪怪的事情。缺点嘛……比较麻烦。

将上网卡转到 ttyUSB 模式

上面做了那么多测试,说明这个上网卡工作在 HiLink 模式。对于一般使用者来说,免驱动即插即用,是极好的;但对于我来说……我要通过 tty 和 AT 指令来读短信啊。所以就需要把模式切换到 ttyUSB 模式。

ID lsusb name mode
12d1:1f01 Huawei Technologies Co., Ltd. USB Mass Storage
12d1:14db Huawei Technologies Co., Ltd. HiLink
12d1:14dc Huawei Technologies Co., Ltd. HiLink
12d1:1001 Huawei Technologies Co., Ltd. E169/E620/E800 HSDPA Modem Modem
12d1:1c05 Huawei Technologies Co., Ltd. Broadband stick (modem on)

这个过程比较波折一些。资料中提到很多种方法,下面是我觉得成功率最高、最简单的。

方法一(确认成功)

新建文件/etc/usb_modeswitch.d/12d1:1f01,输入内容

然后重启。lsusb 可以按到已经工作在了 Modem 模式下。再用 ls /dev | grep ttyUSB 就可以看到三个 ttyUSB 设备了。

按说此时就能直接用了。不过为了避免以后麻烦,我们再多做一点东西。

我们可以使用 screen /dev/ttyUSB2 来进行控制。如果 screen 之后发现怎么敲键盘都没反应就说明不是 ttyUSB2,就换其他的。

输入

查看当前模式,最好能记录下来。然后再输入

就可以让网卡以后都工作在这个序列设备模式上。当然,如果想切换回来,也很简单,输入

就好了。其中最后的 375 是第一步记录下来的数字。

之后删除前面创建的/etc/usb_modeswitch.d/12d1:1f01 文件。

拔下上网卡,插到其他 Linux 电脑上——是不是发现出现了 ttyUSB 设备了呢?这时候再用 lsusb 看设备,会发已经变成了最后一个模式——能用就行了呗。

方法二(没有继续试下去)

工作在 HiLink 模式下,看 ip a,会多出来个 eth1 网卡。然后就有人找到了方法开启调试(debug)模式:

会出现两个 ttyUSB 设备。想办法连接上去,然后用前面的 AT 指令弄成个永久的 ttyUSB 模式——我没有做继续尝试。tty 一直都是黑屏,可能是波特率设置不太对的原因吧。

测试发短信

我们就不亲自用 AT 指令来发短信了,找现成工具代劳吧。

然后进行一下配置

Port 选我们能用的那个 ttyUSB 设备。 Connection 可以在这里找到。我选择了 at19200。其他保持默认。

最后,确认一下信息

发个短信试试

获取和转发短信

在收到短信后,上网卡会通过内部私有指令第一时间将短信读出来、给网络发 ACK 消息、存储到内部 Inbox 里。所以直接用 AT 指令是获取不到短信的!这里我暂时没搞定。


没搞定的话……就又在深水鱼上 20 元包邮了个华为 E220。这个东西插上去就直接有两个 ttyUSB,而且 ttyUSB1 是我们需要的接口。省事很多。

方案一: 使用 gammu-systemd

我们的逻辑是这样的: 使用 gammu-smsd 服务获取短信,存储在 sqlite 里面。写一个 Python,定时查看 sqlite 内容,找到没处理的短信,进行转发。这样的好处是有完整的记录,万一转漏了,之后也能再把短信找到。

所以第一步是安装一些东西:

这里安装了 gamu-smsd 和 python 的接口,并且还有 sqlite 及其接口。

如果使用 Conda 来安装的话,可以这样玩:

安装后,编辑/etc/gammu-smsdrc 文件:

最后是创建一个 smsd.db 的 sqlite 数据库。我们找到/usr/share/doc/gammu/examples/sql,这里面有例子。

OK,准备工作做完了,这样新来短信会直接被存储到这个 sqlite 数据库中。

我们使用如下的 Python 代码来完成短信转发这件事儿:

同样,加入 Crontab 豪华套餐,开始享受短信转发。

方案二: 直接使用 gammu

这个不想写了。大致思路是,只使用 gammu,不使用 gammu-smsd。每次直接从 sim 卡中手动获取短信,然后进行转发,并删除已经转发过的短信。应该和上面的代码差不多。

总结

不难,就是 Debug 比较费钱。Debug 过程总共浪费了 30 多条短信

我们还可以再转发之前加一层过滤,避免转发垃圾短信——嗯,搞个 SVM 分类器?反正文本都已经拿到了,怎么玩就随意了吧?

同样的,我们还可以将短信推送到 Telegram 上、Wechat 上、邮件上,甚至微博和 Twitter 上。甚至可以搞一个自动展示短信的网站——随意啦。

参考资料

发表评论

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