Simple Life

和这个世界交手这许多年   你是否光彩依旧,兴致盎然...

您现在的位置是:首页 爱折腾 爱折腾详情

wavecom短信猫使用AT指令发短信

发布时间:2015-10-18 作者:Felix 浏览(2263)

        短信猫,是一种用来收发短信的设备,他和我们用的手机一样,需要手机SIM卡的支持,在需要收发短信的时候,在短信猫里面插入一张我们平时用的手机卡,插上电源,通过(USB或者串口、网口)数据线和电脑相连可以实现短信收发的功能。因为工作中开发的项目需要提供给公安部门用,必须部署在内网环境,某种功能需要发短信,然后想到了短信猫。

如何使用亲测有效!

        硬件调试真的很难搞,网上的教程千奇百怪,很多很久远了,不少坑。这里整理了我实现了的。

        这里使用的是wavecom的短信猫,电脑上安装usb转串口驱动,然后连接短信猫。

        mac系统在终端执行ls /dev/cu.* 看到有/dev/cu.usbserial,说明已经成功连接上了,windows下直接看usb下com口。(连接的时候千万不要直接拔掉,不然电脑会自动重启

        短信猫主要通过AT指令发送短信,Text模式和PDU模式。使用Text模式收发短信代码简单,很容易实现,最大缺点不支持中文短信。PDU模式不仅能发送中文短信,也能发送英文短信。PDU收发短信有三种编码可用:7-bit、8-bit和UCS2编码。7-bit编码用于发送普通的ASCII字符,即英文短信,最多可发送160字符。8- bit编码通常用于发送数据消息。UCS2编码用于发送Unicode字符,可发送中文字符,最多发送70字符,缺点是比较复杂。


        使用串口调试工具可以简单地测试一下,例子如下:

       1.Text模式(向号码为15050850677的手机发送“TEST”):

 AT                        //发送AT 返回OK 连接成功
 OK
 AT+CMGF=1                 //设置为Text模式
 AT+CMGS="15050850677"     //发送指令,双引号内改为对用手机号码
 > TEST(+^z,十六进制的1A)    //返回字符串中有OK 发送成功 >号为设备返回字符

 

        2.PDU模式(向号码为15050850677的手机发送“你好”):

 AT                        //发送AT 返回OK 连接成功
 OK
 AT+CMGF=0                 //设置为PDU模式
 AT+CMGS=19                //发送指令,更改为对应PDU编码的长度计算方法在后面
 > 0011000D91685150800576F70008C4044F60597D(+^z,十六进制的1A)   //返回字符串中有OK 发送成功

 

        这里着重介绍下PDU的发送方式,一般的PDU编码由A B C D E F G H I J K L M十三项组成。
A:短信息中心地址长度,2位十六进制数(1字节)。
B:短信息中心号码类型,2位十六进制数。
C:短信息中心号码,B+C的长度将由A中的数据决定。
D:文件头字节,2位十六进制数。 
E:信息类型,2位十六进制数。
F:被叫号码长度,2位十六进制数。
G:被叫号码类型,2位十六进制数,取值同B。
H:被叫号码,长度由F中的数据决定。
I:协议标识,2位十六进制数。
J:数据编码方案,2位十六进制数。
K:信息有效期,2位十六进制数。
L:用户数据长度,2位十六进制数。
M:用户数据,其长度由L中的数据决定。J中设定采用UCS2编码,这里是中英文的Unicode字符。

     用一个例子说明整个过程~
        短信中心:+8613800100500(可以查询各个SIM卡得短信中心,填写错误是发送不出去的)
        收信号码:+8613401041516
        短信内容:我爱听评书

     第一步——格式化短信中心号码
     1 - 要去掉“+”号,然后看看长度要是奇数的话就在末尾追加一个“F”。

          +8613800200500 >>>> 8613800100500F
     2 - 将奇数位和偶数位交换位置。
          8613800100500F >>>> 683108100005F0
     3 - 在前面加上“91”,是国际化的意思。
          683108100005F0 >>>> 91683108100005F0
     4 - 最后算一算它有多长了,把长度除于2,再把结果转换为2位的16进制数,加在最前面。
          91683108100005F0长16 16/2=8 8的16进制“08” 一定要注意是2位
          91683108100005F0 >>>> 0891683108100005F0
      短信中心号码就处理完了,下几一步有类似的算法。

     第二步——格式化收信号码
     1 - 要去掉“+”号,然后看看长度要是奇数的话就在末尾追加一个“F”。

          +8613401041516 >>>> 8613401041516F
     2 - 将奇数位和偶数位交换位置。
           8613401041516F >>>> 683104011415F6

     第三步——格式化发送内容
     1 - 把字符串转换为Unicode格式。(转换函数我写过了,直接拿去用好了)
          我爱听评书 >>>> 62117231542C8BC44E66
     2 - 把串Unicode码的长度除于2,再把结果转换为2位的16进制数,加在最前面。
          62117231542C8BC44E66长20 20/2=10 10的16进制“0A”
          62117231542C8BC44E66 >>>> 0A62117231542C8BC44E66

     先看看我们都准备什么了,再继续~
           格式化后的短信中心:0891683108100005F0
           格式化后的收信号码:683104011415F6
           格式化后的发送内容:0A62117231542C8BC44E66

     第四步——组合处理
     1 - 算一下收信号码的长度,不包括“+”号。这个收信号码指的是+8613401041516,而不是683104011415F6。
          +8613401041516 >>>> 8613401041516 长度为“OD”(2位16进制数表示)
     2 - 在长度前后分别加“1100”。
          OD >>>> 1100OD
     3 - 如果收信号码是手机的话就在后面追加“91”,如果是小灵通的话就要追加“81”。
          +8613401041516是手机号码所以加“91”
          11000D >>>> 11000D91
     4 - 11000D91 + 格式化后的收信号码 + “000800” + 格式化后的发送内容
          11000D91 >>>> 11000D91683104011415F60008000A62117231542C8BC44E66
     5 - 计算上面那一大字符串的长度除于2,10进制表示。
          11000D91683104011415F6008000A62117231542C8BC44E66长50 50/2=25

     嗯,咱再看看手里都有啥了~
          格式化后的短信中心:0891683108100005F0
          实际的发送内容:11000D91683104011415F60008000A62117231542C8BC44E66
          发送内容的长度:25
          都准备好了我们可以发短信啦
     最后一步——通过AT命令发送PDU短信
          AT+CMGF=0 <Enter> (告诉它你要发的是PDU类的短信)
          OK (这是它返回的它说:“我已经准备好了”)
          AT+CMGS=25 <Enter> (告诉它你要发的实际长度)
          >0891683108100005F011000D91683104011415F60008000A62117231542C8BC44E66 <Ctrl+Z> (看到它返回“>” 在后面输入格式化的短信中心+实际的发送内容最后按Ctrl+Z发送)
          如果最后返回不是“ERROR”,那就是发送成功咯~!

      简化:

              现在的SIM卡貌似内置了缺省短信中心号码,经过试验,在上述第四步的第五点算出发送内容和长度后,在开头加上'00'意为取sim内置短信中心也可以发送成功。也就是说实际发送内容为0011000D91683104011415F60008000A62117231542C8BC44E66,长度计算不变,还是25。

       python操作串口可以使用pyserial库,附上简略代码:

import serial
       
sa = serial.Serial(port="/dev/cu.usbserial", baudrate=9600, timeout=3)
sa.write("ATZ\r")
sa.write("AT+CMGF=1\r")
sa.write("AT+CMGS="18888888888\r")
sa.write("helloworld")
sa.write(chr(26))
print sa.readlines()
sa.close()

        原创文章如转载,请注明出处


基于 Django 搭建

服务器采用的 阿里云

域名来自 万网

苏ICP备16015443号

©2015-2016 felixglow.com.

GitHub

Design by Felix