GPRS发送中文短信--Text模式转换为PDU模式

上一篇我们用AT指令发送了带中文的短信,发送的数据是由号码和内容经过转换成PDU模式,下面我们来分析转换的过程。
1.Text模式和PDU模式的区别
发送短消息常用Text和PDU(Protocol   Data   Unit,协议数据单元)模式。使用Text模式收发短信代码简单,实现起来十分容易,但最大的缺点是不能收发中文短信;而PDU模式不仅支持中文短信,也能发送英文短信。PDU模式收发短信可以使用3种编码:7-bit、8-bit和UCS2编码。7-bit编码用于发送普通的ASCII字符,8-bit编码通常用于发送数据消息,UCS2编码用于发送Unicode字符。一般的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字符。
(1)Text Mode是纯文本方式,可使用不同的字符集,从技术上说也可用于发送中文短消息,但国内手机基本上不支持,主要用于欧美地区。
(2)PDU Mode被所有手机支持,可以使用任何字符集,这也是手机默认的编码方式。Text Mode比较简单,而且不适合做自定义数据传输.
2.转换实例


我的号码:          +86123456
接收方号码:       +10086
短信内容:          一条测试信息、

1.对我的号码处理:
(1) 将我的号码去掉“+”号,看看长度是否为偶数,如果不是,最后添加F.   
    处理后=>86123456
(2) 将奇数位和偶数位交换。
     处理后=>68214365
(3) 将短信息中心号码前面加上字符91,91是国际化的意思
    处理后=>9168214365
(4) 算出 (3)号码长度,结果除2,格式化成2位的16进制字符串,10 / 2 = 5 => "05"
(5)05加在91前面,处理后我的最终号码==>059168214365
2.接收方号码处理:
(1)将接收方号码去掉+号,看看长度是否为偶数,如果不是,最后添加F
     处理后=>6810086F
(2) 将奇数位和偶数位交换
      处理后接收方号码=>860180F6
3.短信内容处理:
(1) 转字符串转换为Unicode代码。每个汉字以及符号都有固定的Unicode代码。用相应的转换器转换

(2) 去掉\u,每个字符长度为4,将字符总长度除2,保留两位16进制数
     即4E0067616D4B8BD54FE1606F=24  /  2=12=>"0C",把它加在4E0067616D4B8BD54FE1606F前
     处理后短信内容=>0C4E0067616D4B8BD54FE1606F
4.组合
(1) 接收方手机号码前加上字符串 11000791(1100:固定,07:手机号码的长度,不算+号,十六进制表示,91:发送到手机为91,发送到小灵通为81)
     X = 11000791860180F6
(2)接收方手机号码后加上 0008AA 和处理后的短信内容:
     Y = X + 0008AA + 0C4E0067616D4B8BD54FE1606F
即:Y =  11000791860180F6 0008AA 0C4E0067616D4B8BD54FE1606F (一共48位)
(3)Y 长度除以2,格式化成2位的十进制数
处理后=>48/2=24,所以CMGS=24
(4)最终代码: 处理后我的号码 +Y
05916821436511000791680180F6 0008AA 0C4E0067616D4B8BD54FE1606F
发送方               接收方                                   短信内容
5.发送
AT+CMGF=0   <回车> <换行>   
OK   
AT+CSCS="GSM"  
OK
AT+CMGS=24<回车> <换行>  
OK
>05916821436511000791680180F60008AA0C4E0067616D4B8BD54FE1606F <Ctrl+Z> <回车><换行>(注意:这里的Ctrl+Z的ASCII值是24,用16进制发送时是1A)