Categories
CDMA

CDMA SMS pdu解码

去年玩过via cdma模组,刚开始对cdma sms pdu真是一脸茫然,意识到我也可能不会长时间做这个,网上这类帖子少之又少,体会初学者的辛苦,重新翻尸体,记录下来。

收到两条短信,现在用AT把它们读取出来。

at+cmgr=5
+CMGR:5,”REC UNREAD”,”15338896020″,”UNKNOWN NUMBER”,”N/A”,176

“0000021002020702c54ce225a8a80601c0089d00031001e801
8e2230018801780193108b09fb087b317b012b6a080162e38c8e6
3b422e07b65980162b942e872e4b3b4246f7a70500162e54bbf9a7
053f67c7e3801729f544c0b108bb423918a75d00163317a70033b0
ae07ce3e00162b943108bb4236b54158a71680162ff5a7283b423
71c33b2b71c29dd80173108b09fb087b317c1a933cb80162b943659
b6a0bb4227122e5c00306081229192611″

at+cmgr=21
+CMGR:21,”REC UNREAD”,”15338896020″,”UNKNOWN NUMBER”,”N/A”,96

“0000021002020702c54ce225a8a806014c084d00031001f8013
e20f00190017801900162dfca7004b1acb1abb4239614c67001629
63b2b12b9827ae310c001729f544c0b108bb423918a75d00163317
a70029f52e07cf0f80306081229192616”

[deli@deli example]$ ./test_pdu_decode
0000021002020702c54ce225a8a80601c0089d00031001e8018e22
30018801780193108b09fb087b317b012b6a080162e38c8e63b422
e07b65980162b942e872e4b3b4246f7a70500162e54bbf9a7053f67
c7e3801729f544c0b108bb423918a75d00163317a70033b0ae07ce3
e00162b943108bb4236b54158a71680162ff5a7283b42371c33b2b7
1c29dd80173108b09fb087b317c1a933cb80162b943659b6a0bb422
7122e5c00306081229192611
sms context == 1/2我愿意是急流,山里的小河,在崎岖的路上,岩石上经过.只要我的爱人,是一条小鱼,在我的浪花中,快乐的游来游去.我愿意是荒林,在河流的两岸
SM_ENCODING == 4
TPA == 15338896020
SCTS == 19:26:11 12/29/08

[deli@deli example]$ ./test_pdu_decode
0000021002020702c54ce225a8a806014c084d00031001f8013e20f
00190017801900162dfca7004b1acb1abb4239614c6700162963b2
b12b9827ae310c001729f544c0b108bb423918a75d00163317a700
29f52e07cf0f80306081229192616
sms context == 2/2,对一阵阵的狂风,勇敢地作战.只要我的爱人,是一只小鸟
SM_ENCODING == 4
TPA == 15338896020
SCTS == 19:26:16 12/29/08

PDU串解析

CDMA的pdu格式与GSM的相差很多,不能直接用肉眼看出来。第一条内容比较长,就拿第二条pdu串来分析吧。
1.首先将PDU串打成PDU包
将PDU串相邻的两个ascii字符拼凑成一个8bit数据

如下:
00 00 02 10 02 02 07 02 c5 4c e2 25 a8 a8 06 01 4c 08 4d 00 03 10 01 f8 01 3e 20 f0 01 90 01 78 01 90 01 62 df ca 70 04 b1 ac b1 ab b4 23 96 14 c6 70 01 62 96 3b 2b 12 b9 82 7a e3 10 c0 01 72 9f 54 4c 0b 10 8b b4 23 91 8a 75 d0 01 63 31 7a 70 02 9f 52 e0 7c f0 f8 03 06 08 12 29 19 26 16

消息传送类型: 0x00 point to point message(表示点对点消息)

下面的内容为短消息的各个字段 每个字段分为三个部分: 字段类型(ID)(8bit)、字段长度(Length)(8bit)和字段内容.

第一个字段: 00 02 10 02
0x00, 表示uTeleserviceID字段
0x02, 字段长度,该长度必须为2,否则为错误的pdu信息

字段内容为:0x1002,十进制是4098,

第二个字段: 02 07 02 c5 4c e2 25 a8 a8
0x02, SMS_TL_ORIG_ADDR 表示 (短信发送地址)
0x07, 字段长度为7
字段内容: 02 c5 4c e2 25 a8 a8
只看前面几个 02 c5 4c e2的:
0000 0010 1100 0101 0100 1100 1110 0010 0010
取第一个bit 0 表示 RIL_CDMA_SMS_DIGIT_MODE_4_BIT 是4bit压缩
第二个bit 0 表示 RIL_CDMA_SMS_NUMBER_MODE_NOT_DATA_NETWORK
下来8个bit 是 00 0010 11 = 11,表示号码长度 为11
由于是4bit压缩 ,后面44个bit(4*11)表示号码,解析出来是
15338896020

第三个字段: 06 01 4c
表示SMS_TL_BEARER_RPLY_OPT

第四个字段:08 4d 00 03 10 01 f8 01 3e 20 f0 01 90 01 78 01 90 01 62 df ca 70 04 b1 ac b1 ab b4 23 96 14 c6 70 01 62 96 3b 2b 12 b9 82 7a e3 10 c0 01 72 9f 54 4c 0b 10 8b b4 23 91 8a 75 d0 01 63 31 7a 70 02 9f 52 e0 7c f0 f8 03 06 08 12 29 19 26 16

0x08, 表示SMS_TL_BEARER_DATA字段(短信内容)
0x4d,字段长度为77

这个字段也分成各个子字段:

第一子字段: 00 03 10 01 f8
0x00
Mesage Id
0x03 内容长度
10 01 f8  === 0001 0000 0000 0001 1111 1000
0001 表示 DELIVER 短信
0000 0000 0001 1111表示 message id.
紧接后面的 1, 表示HEADER_IND

第二个子字段:01 3e 20 f0 01 90 01 78 01 90 01 62 df ca 70 04 b1 ac b1 ab b4 23 96 14 c6 70 01 62 96 3b 2b 12 b9 82 7a e3 10 c0 01 72 9f 54 4c 0b 10 8b b4 23 91 8a 75 d0 01 63 31 7a 70 02 9f 52 e0 7c f0 f8
0x01, 字段类型
0x3e(62),字段长度
20 f0 01 === 0010 0000 1111 0000 0000 0001
0x20 的前5个bit为00100, 为0x04, 表示短信编码方式为RIL_CDMA_SMS_ENCODING_UNICODE (UNICODE)
0x20 的后3个bit, 0xf0的前5个bit,为 000 1111 0, 即0x1e (30),表示有30个UNICODE 字符。0xf0的后3个bit,0x01的8个bit,再加上0x90的前5个bit,

0000 0000 0011 0010 拼成一个16位数是 0x0032 表示字符 :2,在vim下了解一个字符的16进制码很简单,光标在该字符,按ga,底端显示结果如下:

<2>  50,  Hex 32,  Octal 062                                  2,1           All

依次下去,内容就是上面运行./test_pdu_decode 的结果: 2/2,对一阵阵的狂风,勇敢地作战.只要我的爱人,是一只小鸟

第三个子字段: 03 06 08 12 29 19 26 16

这是一个时间戳字段: 08年12月29号19时26分16秒(短消息发送时间)

字符串分析结束。当然,还有很多可选项在这条短信没有加上,更完整的SMS格式,请参考CDMA SMS standard on 3GPP2 website.

实际编码时,一个while循环遍历,再加上switch简单的状态机即可。

长短信何在?

用的这个模组,不支持长短信,厂家回答“作了预处理,把User Data Header去掉了,因为客户一般不愿意自行处理这个User Data Header,他们只要内容、号码等其它信息。所以,模块送出的PDU中不含有User Data Header。”

为实现长短信的拆分和组合功能,终端应支持 IS637C 协议中关于长短消息处理的参数 HEADER_IND,以及在短消息数据中增加对 User Data Subparameter 参数增加用户数据消息头(User Data Header)和短信拆分、组合的处理。HEADER_IND 为消息头标识位,用于指示 User Data Header 是否包含消息头, 若包含消息头则 HEADER_IND 设置为’1’,否则设置为’0’。具体的拆分与组合,请参考IS637C,或 《中国电信CDMA终端需求规范-SMS分册-V1.0》。需要说明的是,对长短信的处理,有的CDMA模组厂家为了让用户省事,帮你处理了用户数据头,正如前面所看到的,自动加上(1/2), (2/2)等,若想自己手动解析,务必跟模组厂家沟通确认好。