C实现GPRS模块发送短信(2)

二、 PDU模式下发送短信流程

Pdu模式发送信息仍然是三步搞定,只不过我们在前期得做一些稍微麻烦的数据转换工作。

我们先来看流程理清脉络:

1.AT+CMGF=0 设置为PDU模式发送中文编码短信
        2.AT+CMGS=信息长度
        3.发送短信

示例:

======================================================================
        AT
        OK
        AT+CMGF=0
        OK
        AT+CMGS=25
        >0891683108100005F011000D91685110906474F90A534E6E058FDC89C1FF01
        ======================================================================

前面的我们容易理解:

“AT+CMGF=0”将发送模式置为PDU模式;
        “AT+CMGS=25”这句CMGS后面跟的不再是电话号码了,而是“信息长度”,这里我加了双引号表示有独特的含义后面解释。

现在分析最关键的地方:

“0891683108100005F011000D91685110906474F90008000A534E6E058FDC89C1FF01”

我们可以将这段头疼的字符串分为三段:

-----------------------------------------------------------------------------------------
        “0891683108100005F0 ”                                          中心号码段
        “11000D91685110906474F9000800”                    收信方号码段
        “0A534E6E058FDC89C1FF01”                                信息段
        -------------------------------------------------------------------------------------------

1. 先来看中心号码段。

关于什么是中心号码我想百度比我解释的更清楚,这里不再赘述了。

我们其实还可以将其再细分:

08        91        683108100005F0
        其中91是国际化的意思,这个作为前缀必须加上。
        683108100005F0是什么意思呢?我们将它奇数位和偶数位反转看看:

“683108100005F0”
        “8613800100500F”

熟悉吗?13800100500是中国移动北京地区的中心号码,86是中国地区的前缀这个大家应该清楚。F呢?因为在进行PDU编码的时候规定了如果号码位数是奇数位那么就要在末尾加F进行补齐,由于我们国家的手机号码位数都是11位,因此要在末尾补F。于是中国移动北京地区的中心号码加86补齐F再奇偶位反转最后加91国际化前缀就由原来的:

“13800100500”
        变成了:
        “91683108100005F0”

接着我们数一下它有多少位,16位,16/2=8,所以我们把整个中心号码组合编码后的长度除以2,最后以十六进制的表示方式加在它的前端就大功告成了。

“0891683108100005F0”

Ok搞定,下一步继续。

======================================================================

2. 收信方号码段。

“11000D91685110906474F9000800”

同样将其细分:

1100 0D91 685110906474F9 000800
        其中“1100”和“000800”分别是收信方号码段固定的前缀和后缀,所以一定要记得加上。
        “685110906474F9”不用讲了,和中心号码段一样的编码方式,原型是:
        “8615010946479”(华清远见北京总部执勤电话)。
        “0D91”需要注意一下,其中这里的“91”和中心号码段的“91”意义不一样了,这里是表示接收方的设备是手机的意思,“81”则是小灵通。“0D”是一个十六进制数,还原为十进制后是13,什么意思呢?接受方的号码是“8615010946479”共13位。

因此接收方电话经偶数位<补齐F>

然后<奇数偶数位反转>

再<加上号码长度>

最后<加上前后缀>最终由:

“8615010946479”

转型为:

“11000D91685110906474F9000800”。

======================================================================

3. 信息段。

“0A534E6E058FDC89C1FF01”

信息段是最简单的,大家需要了解GPRS以PDU模式发送信息时,其内容是以unicode的方式编码的。

其中:

“534E6E058FDC89C1FF01”
        还原成GB汉字编码为:
        “华清远见!”
        其编码(十六进制)长度是20位,20/2=10,10的十六进制表示方式是0X0A。因此信息段的最终编码为:
        “0A534E6E058FDC89C1FF01”

4. 组合。

如果把发短信比喻为一次快递的投递过程,那么过程如下:

首先是中心号码(相当于我们的邮局);

接着是接收方号码段(相当于我们的收信人地址);

最后是信息段(就是你的信件了)。

OK,组合结果就是:

“0891683108100005F011000D91685110906474F90008000A534E6E058FDC89C1FF01”

至此,PDU的编码就正式结束了。

不过我们还有最后一件事,那就是前面提到的那个“信息长度”。

邮局是国家的公有的,我们无权去干涉,但是收信人和信息是我们自己制定的,因此我们要精确掌握自己所属的信息。

于是我们将中心号码段剔除,变为:

“11000D91685110906474F90008000A534E6E058FDC89C1FF01”

计算一下字符串长度,50位。OK,50/2=25。

于是在PDU模式下,我们所谓的“信息长度”:AT+CMGS=25。

回顾一下PDU模式下的发信息流程:

======================================================================
        AT
        OK
        AT+CMGF=0
        OK
        AT+CMGS=25
        >0891683108100005F011000D91685110906474F90A534E6E058FDC89C1FF01
        ======================================================================

一定要记得最后输完信息编码后要按“ctrl+z”而不是回车。

最后如果返回值不是ERROR,那么就恭喜你,大功告成了!

另附Linux下GPRS模块发送短信的C语言代码,由于时间匆忙没有注意内存对齐、代码优化等细节,望广大读者见谅,有何疑问或建议请发邮件:

hostfj@163.com 
farsight.fj@qq.com

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wywxps.html