Featured image of post 利用GSM模块给NAS增加短信功能

利用GSM模块给NAS增加短信功能

一、前序

大概在小学快上初中的时候吧,那时候喜欢泡各种“手机游戏软件分享”类似的论坛,基本都是柯林程序搭建的;当时这些程序源码对于用户注册、找回密码这些动作验证,都和一个叫做“短信云猫”的东西有关。

像现在,这些动作基本都是以“收取验证码”的形式作为验证,而“云猫”却恰恰相反,它是通过发送指定“口令”给指定号码的形式作为验证;他们之间的区别和优势这里就不做比较了,虽然“云猫”这种东西好像逐渐淡出了生活的视线,但这种曾经的过往记忆还是比较深刻。

回到现在,我们现在每个人有多张手机卡很正常,工作学习可能都有一张卡,像我初中时期办的一张移动卡至今还在用,虽然电话基本已经不打了,除了怀旧之外,还绑定了不知道多少个网站APP,所以换是不可能换的,这辈子都不可能换卡的!@(你懂的)

刚好最近在慢慢学Go,也凑巧知道有个包能支持串口通信,于是这件事就提上了日常,前后折腾了一个礼拜左右(等快递…),能够顺利收取短信,后期可能慢慢加其它功能。

** Ps:虽然随便买个二手机也能插卡,但想要享受折腾的乐趣,那就得折腾,嘿嘿!@(哈哈) **

二、硬件准备

1、NAS

其实这也谈不上是一个NAS,是我在闲鱼收的矿渣“我家云”套壳产品联想云,系统刷的是别人搞好的固件Armbian,结果我觉得不好用,把所有无关组件全删了;然后装了宝塔、V2、Zerotier和Samba,又塞进去一块1T的硬盘;放家里做家庭代理,内网穿透共享文件夹用用。

** 刚好机器后面还有空余的USB口,于是想着也可以刚好把它利用起来。**

2、USB转TTL模块

我用的型号是CH340G,USB不能和通信模块直接通信,所以需要一个模块中转一下;而驱动方面支持的也比较好,Windows 直接驱动精灵扫描一下直接安装就行,Linux 好像直接是自带就有,反正我的Armbian没有额外安装,插上就能直接用,不过好像就是版本有点老。

3、GSM 通信模块

通信模块用的型号是SIM800C,支持移动联通卡,通信是基于GSM 的2G网络,所以购买的时候一定要查清楚自己地区2G有没取消;坐标上海已经全面取消了联通2G,我刚测试的时候差点帮我整懵了还以为是模块有问题。@(喷)

4、闲置手机卡

我的目标是要托管一张我自用的中国移动的正常手机卡,但测试用的是一张香港手机卡,也是中国移动信号,所以不影响。


Ps:USB转串口和GSM模块都是淘宝同一个店铺买的,一共不到50块钱,价格一般般吧。

三、软件准备

刚拿到模块的时候需要对模块进行调试测试,确保工作正常,所以需要一些串口调试助手软件进行测试。

  • Windows 推荐 野火调试助手,这软件一般买模块的时候,最好直接问商家要,有问题也方便直接沟通。
  • Linux 推荐 minicom,这是一款命令行调试工具;使用之前先确保驱动正常,再插上模块,随后在/dev目录下面就会出现串口路径;我的是/dev/ttyUSB0,在自己敲代码写程序的时候,这个路径就是串口名。

** 然后其它软件,就靠自己写了,比如本篇文章,我只完成了基本的收信读取功能,反正只要你会写,功能总是可以搞定滴! **

四、图片展示

联想云NAS

平常放在路由器旁边,还有一个小风扇,买了大概半年多了吧,取代了我之前的树莓派3B 联想云.jpg 联想云 (2).jpg 联想云 (3).jpg

模块

USB转TTL和GSM模块使用杜邦线连接好,注意接线,TX和RX互接,GND接地,VCC五伏供电 USB转TTL.jpg SIM模块.jpg

QQ换绑测试

换绑自己玩游戏的QQ小号作为测试,成功发送了验证码
QQ换绑.png

短信收取

代码跑起来之后,成功收到了来自腾讯的短信验证码,看发信号码,也属于香港地区 短信收取.png

五、成品代码

 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

package main

import (
	"fmt"
	"github.com/tarm/serial"
	"log"
	"strings"
)

func main() {
	c := &serial.Config{Name: "/dev/ttyUSB0", Baud: 115200}
	com, err := serial.OpenPort(c)
	if err != nil {

		log.Fatal(err)
	}

	n, err := com.Write([]byte("AT\r\n"))
	//com.Write([]byte("AT+CMGF=1\r\n"))
	//n, err := com.Write([]byte("ATE0\r\n")) //关闭回显
	//n, err := com.Write([]byte("AT+CMGR=14\r\n"))
	//n, err := com.Write([]byte("ATD008618209809694;\r\n"))
	if err != nil {

		log.Fatal(err)
	}

	data := ""
	buf := make([]byte, 128)
	for {
		n, err = com.Read(buf)
		if err != nil {

			log.Fatal(err)
		}

		data += string(buf[:n])
		if n < 32 {
			if strings.Contains(data, "CMTI") {
				header := strings.Split(data, ",")
				smsId := clearInvalidChar(header[1])
				log.Printf("收到一条新短信[%s]>>>\n", smsId)

				com.Write([]byte(fmt.Sprintf("AT+CMGR=%s\r\n", smsId)))
			} else if strings.Contains(data, "CMGR") {
				log.Println("短信读取内容如下>>>")

				arr := strings.Split(data, "\r\n")
				info := strings.Replace(arr[1], "\"", "", -1)
				header := strings.Split(info, ",")
				content := arr[2]

				log.Println("发信号码:" + header[1])
				log.Println("发信时间:" + header[3] + " " + header[4])
				log.Println("短信内容:" + content)
				log.Println("--------------------------- \n")
			} else {
				log.Println("未知数据:" + data)
			}

			// 清空数据
			data = ""
		}
	}
}

func clearInvalidChar(str string) string {
	str = strings.Replace(str, " ", "", -1)
	str = strings.Replace(str, "\r", "", -1)
	str = strings.Replace(str, "\n", "", -1)

	return str
}

六、最后

  • 这个GSM模块不仅仅只是收发短信,还可以打电话、GPRS通信,还是挺好玩的,可玩性比较高,推荐点赞!

  • 本篇的代码只是Demo测试,能够勉强跑起来;短信的解析只是文本模式简单的字符串切割,如果用PDU解析的话会更加标准。

  • 整个过程参考了各种资料,因为涉及的文档地址太多,最后我也不记得到底看了多少资料,所以就不一一列出来了;总之:感谢各位大佬前辈。

本文采用 CC BY 4.0 协议,转载请署名并注明出处。
最后更新于 2021-08-02 15:49:16
使用 Hugo 构建
主题 StackJimmy 设计