小白刚开始工作,需要做支持cmda短信的收发,于是忙碌的时间开始 了。小白在网络上辗转搜索,找到了一个讲的很好的 cmda pdu 解码的博客
http://blog.csdn.net/mcu_hong/article/details/7625478 这里非常感谢,博客主人的分享,但是,博客主人写的东西并没有涵盖完全,
只是将到了普通短信和中文编码的部分,并没有对 长短信 和英文编码 做过多的讲解。
因此,本编文章主要讲解 长短信 与 普通短信的区别,7bit 编码时的注意事项。
在您阅读本文之前, 请务必阅读 上文。这是文中提到的 http://www.3gpp2.com/Public_html/specs/C.S0015-A_v1.0_111403.pdf 3gpp2对cdma短信的有关标准。
对于短信, 我们关注的主要是两个东西, 发送地址(谁发的,发给谁的),消息内容(文本是什么)。
我用手机发送了一个串 hello , 这是截取的PDU, 下面我先对这个PDU, 进行分析。
0000021002020702c6049064c4d40601fc081b00031000200106102e8cbb366f03061409011126310a01400d0101
以上遵循CDMA 的 PDU格式
所有的 PARAMETER_ID 在下表中标示
按照 文档 中提供的格式,我们以此解析, 参见文档 C.S0015-A_v1.0_111403.pdf P49
1、 00 SMS_MSG_TYPE :
00 表示 SMS Point-to-Point 点对点传输
2、 00021002 Teleservice Identifier
The Teleservice Identifier parameter identifies which upper layer service access point is sending or should receive this message
00 = PARAMETER_ID , 02 = PARAMETER_LEN, 1002 = Parameter
3、 020702c6049064c4d4 Address Parameters
The address parameters have the following variable-length format:
020702c6049064c4d4
02 = PARAMETER_ID , 这里表示源地址 Originating Address parameter, this field shall be set to ‘00000010’.
07 = PARAMETER_LEN, SMS message parameter length.
02c604 = 00
00 0010 11
00 01
10 0000 0100
第一个 0 = DIGIT_MODE , 4-bit DTMF -->This field indicates whether the address digits are 4-bit DTMF codes
第二个 0 = NUMBER_MODE, not a data network address -->This field indicates whether the address type is as defined a data network address.
接下来的8个bits
00 0010
11
--> 0B(十六进制), 11(十进制) 表示 后面紧跟了 一个 11 位的号码。
接下来的
0001 --> 4个2进制数 ,表示一个十六进制数, 1
接下来 1000 --> 8
最后解析出来 号码是: 18124193135 (当收到短信时,这是一个源地址)
4、0601fc Bearer Reply Option
The Bearer Reply Option parameter is used to request return of an SMS Acknowledge Message. The Bearer Reply Option parameter has the following fixed-length format:
06 = PARAMETER_ID
01 = PARAMETER_LEN
fc -> 1111 1100 1111 11 = REPLY_SEQ , 00 = RESERVED (保留位通常补0)
这个域, 说实话我也不知道是干什么用的, 如果你不需要解析这个域的话, 直接pass掉就好了。
5、081b00031000200106102e8cbb366f03061409011126310a01400d0101 Bearer Data
这个域里面有大量的子域
The Bearer Data parameter has the following variable-length format:
我们分别用不同的颜色标示,以示区分
081b00031000200106102e8cbb366f03061409011126310a01400d0101
08 = PARAMETER_ID
1b = PARAMETER_LEN
所有的 SUBPARAMETER_ID 在下表标示。
5.1 0003100020 Message Identifier
The Message Identifier subparameter provides the message type and a messageidentification that can be used for acknowledgment.
The Message Identifier subparameterhas the following fixed-length format:
00 ---> SUBPARAMETER_ID
03 --> SUBPARAM_LEN
1 --> MESSAGE_TYPE : Deliver (mobile-terminated only) (表示短信以此为终止,当前设备)
0002 --> MESSAGE_ID
0 --> 0000 第一个0 表示 HERDER_IND 这个域表示是不是长短信(长短信有数据头,下面我会讲到), 0 : 不是, 1 : 是
000 后面的三个 0 RESERVED
5.2 0106102e8cbb366f User Data
The User Data subparameter has the following variable-length format:
01 = SUBPARAMETER_ID
06 = SUBPARAM_LEN
102e8cbb -- > 0001 0
000 0010 1
110 1000
1100 1011 1011
0001 0 = MSG_ENCODING : 表示 7-bit 编码, 00100 表示 16-bit unicode 编码, 00000 表示 8-bit 编码
000 0010 1
--> 5 (十进制) = NUM_FIELDS :表示后面有5个 7-bit 编码的数据
(
注意
, 当有 UDH 时, 这个长度也包含有 UDH, 还有个 7bit 对齐的问题,下面会讲到)
110 1000
--> 0x68 (ASCII 码) : h
1100 101 --> 0x65 : e
注意: CDMA 的 7-bit编码, 跟 GSM 的 7-bit 编码有区别, 如果你正在做了 GSM 的 7-bit编码, 请不要直接用过来
以此解析完所有的bit,
内容就出来了: hello
5.3 0306140901112631 Message Center Time Stamp
The Message Center Time Stamp subparameter may be included with SMS messages sent from a Message Center.
The Message Center Time Stamp subparameter has the following fixed-length format:
14 YEAR, 09 MONTH, 01 DAY, 11 HOURS, 26 MINUTES, 31 SECONDS
2014-09-01 11:26:31
5.4 0a0140 Reply Option
5.5 0d0101 Language Indicator
我们来看一条长短信, 我接受到了一条英文 7-bit编码的 长短信,并把它截取出来
0000021002020702c6049064c4d40601fc08a00003100028018e150028001818100b3ecd3bb3efcfa74eecf9f7e45db33e9dd9f4aed1bf66dd3bb3f6e7b72ecd3eb96ed3b37e9e7c346dcfab3e8dfb34e8dfb362e9fb366cdf9f669d9b366cd995754e4ba3f5d3b33ece7a73ae93b746fd9b37e774a766cdfbb5efdd9f7e7dfb33e9dd9f669cfbf3efcfb3669e9a36ae9fb34eecfa7769dba7767df9f7ae84ba12e849e23a5aa72003061409040928320d0101
参照前面讲的步骤,我们以此解析, 第 5 节前面的都是一样的。 现在重复 5 节的步骤,来解析长短信,上了背景色的部分是我们需要在第5 节解析的内容
08a00003100028018e150028001818100b3ecd3bb3efcfa74eecf9f7e45db33e9dd9f4aed1bf66dd3bb3f6e7b72ecd3eb96ed3b37e9e7c346dcfab3e8dfb34e8dfb362e9fb366cdf9f669d9b366cd995754e4ba3f5d3b33ece7a73ae93b746fd9b37e774a766cdfbb5efdd9f7e7dfb33e9dd9f669cfbf3efcfb3669e9a36ae9fb34eecfa7769dba7767df9f7ae84ba12e849e23a5aa72003061409040928320d0101
5. 08a0
5.1 0003100028 这里, HERDER_IND 解出来是 1 说明 User Data 中有用户数据头。
5.2 018e150028001818100b3ecd3bb3e...
01= SUBPARAMETER_ID
8e = SUBPARAMETER_LEN --> 142 byts
150028 --> 0001 0101 0000 0000 0010 1000
0001 0 MSG_ENCODING : 表示 7-bit 编码
101 0000 0 --> 160 (十进制) = NUM_FIELDS :表示后面有160 个 7-bit 编码的数据
000 0010 1 : UDHL (User Data Header Length) : 05 UDH 的解析 参照 User Data Header
28001818100b3e --> 0010 1000 0000 0000 0001 1000 0001 1000 0001 0000 0000 1011 0011 1110
000 0000 0 -> iei : 0x00
000 0001 1 : iei Length 0x03
000 0001 1 : 参考号: 0x03
000 0001 0 : 总条数 : 0x02
000 0000 1 : 第几条 0x01
--------------------------------------------------------------------------------------------------------------------------------------------- UDH 到这里结束
这里 UDH 有 6 byte : 6 * 8 = 48 bit 不能被 7 整除即不能刚好补满 7-bit编码的数据。所以这里需要 留 1 个 bit 补齐 7-bits 数据格式。
0 UDH reserved
11 0011 1 : 0x67 -> g
依次解析出来内容是: glingogiinggod.lgingi.holmingvsmelizrniloisphmgjgholiholl.Ollloglillllle.Tr.Guilglsig.Imhollog:)llonkongogolgingligogogllithm.Olinginimingogo.B.B.B'D:-)d
5.3 0306140904092832 : Message Center Time Stamp 2014-09-04 09:28:32
5.4 0d0101 Language Indicator
6 字符的编码解码
默认我们的程序可以识别保存并输出的是 utf-8 的编码, 所以当你收到或传输的编码格式不是 utf-8 的编码格式时,就需要对字符进行编解码。
编码: utf-8 ----> unicode 或 7-bit
解码: unicode 或 7-bit --> utf-8
有关 16-bit 编解码 的部分,参见 http://blog.csdn.net/iefreer/article/details/4836844
参考文献 :
1. cdma pdu 解码 http://blog.csdn.net/mcu_hong/article/details/7625478
2. User Data Header
3. http://www.3gpp2.com/Public_html/specs/C.S0015-A_v1.0_111403.pdf (不建议直接打开,用下载工具下载出来)