田海立@CSDN
2012-06-29
WAP PUSH是封装在SMS PDU中的,所以要解析WAP PUSH,首先要先看SMS PDU编码,这是SMS / MMS / WAP PUSH等业务的基础。WAP PUSH是通过发送给终端的,所以本文主要看Delivery类型的PDU编码。另外,如果PDU要封装的内容过长,会接收到拆分过的多条SMS,本文对接收到的多条Concatenated SMS的拼接也做了阐述。
一、单个SMS PDU的封装
下面是接收到的一个完整PDU:
0891683108200105f04408a0015608860104216092902512236e0605040b8423f0120601ae02056a
0045c60c033231312e3133362e3130372e37382f646f776e2e7068703f703d413063303026733d38
3500080103e68e8ce68fa1e882a1e5b882e58588e69cbaefbc8ce6aca2e8bf8ee4bdbfe794a8e689
8be69cbae8af81e588b8e38082000101
(注:因显示的原因,人为的进行了分行,其实这个包中间并没有换行)
SMS PDU的封装并不是在所有的位置都有固定的涵义,它是逐个扫描的,解析完上一个字段,才知道接下来的含义,或者后面字段的长度。
1. 短信中心
SC长度
为08,所以接下来的8字节为短信中心内容
SC 91683108200105f0
91为国际号,加上’+’号;
后面的号码编码规则为GSM BCD:683108200105f0 –> 8613800210500
所以,得到短信中心号码:+8613800210500
现在PDU扫描到了红色处(绿色部分已经扫描结束):
0891683108200105f04408a0015608860104216092902512236e0605040b8423f0120601ae02056a
0045c60c033231312e3133362e3130372e37382f646f776e2e7068703f703d413063303026733d38
3500080103e68e8ce68fa1e882a1e5b882e58588e69cbaefbc8ce6aca2e8bf8ee4bdbfe794a8e689
8be69cbae8af81e588b8e38082000101
2. FirstByte:
0x44 = 0100 0100
bit1.bit0: mti
00 Delevery
01 Submit
10 Status Report
bit7: TP-Reply-Path
1 有
0 无
bit6: 指示是否有userdata header (UDH)
1 有
0 无
bit4.bit3: TP-Validity-Period (submit类型的PDU才有意义)
00: len=0
10: len=1
01/11: len=7
现在PDU扫描到了红色处(绿色部分已经扫描结束):
0891683108200105f04408a0015608860104216092902512236e0605040b8423f0120601ae02056a
0045c60c033231312e3133362e3130372e37382f646f776e2e7068703f703d413063303026733d38
3500080103e68e8ce68fa1e882a1e5b882e58588e69cbaefbc8ce6aca2e8bf8ee4bdbfe794a8e689
8be69cbae8af81e588b8e38082000101
3. 发送方地址(Originating address)
地址长度:
长度Length = 08
得到地址占用的字节数(包含长度本身): 2 + (Length + 1) / 2 = 6
地址在08a001560886
08 a001560886
TOA: 0xA0 = 1010 0000
bit7: 必须为1
bit6...bit4: ton = 010
000 TON_UNKNOWN(0)
001 TON_INTERNATIONAL(1)
010 TON_NATIONAL(2)
011 TON_NETWORK(3)
100 TON_SUBSCRIBER(4)
101 TON_ALPHANUMERIC(5)
110 TON_ABBREVIATED(6)
所以,发送方地址为:
01560886
-> 10658068
现在PDU扫描到了红色处(绿色部分已经扫描结束):
0891683108200105f04408a0015608860104216092902512236e0605040b8423f0120601ae02056a
0045c60c033231312e3133362e3130372e37382f646f776e2e7068703f703d413063303026733d38
3500080103e68e8ce68fa1e882a1e5b882e58588e69cbaefbc8ce6aca2e8bf8ee4bdbfe794a8e689
8be69cbae8af81e588b8e38082000101
4. TP-Protocol-Identifier(TP-PID)
TS 23.040 9.2.3.9
01
现在PDU扫描到了红色处(绿色部分已经扫描结束):
0891683108200105f04408a0015608860104216092902512236e0605040b8423f0120601ae02056a
0045c60c033231312e3133362e3130372e37382f646f776e2e7068703f703d413063303026733d38
3500080103e68e8ce68fa1e882a1e5b882e58588e69cbaefbc8ce6aca2e8bf8ee4bdbfe794a8e689
8be69cbae8af81e588b8e38082000101
5. TP-Data-Coding-Scheme
(TS 23.038)
0x04 = 0000 0100
bit7: 如果此位为0
bit6: automaticDeletion
bit5: userDataCompressed
bit4: hasMessageClass
if (!userDataCompressed) // bit5
bit3...bit2:
00 ENCODING_7BIT
10 ENCODING_16BIT
01/11: ENCODING_8BIT
bit7...bit4: 如果这四位为1111
bit2:
0 ENCODING_7BIT
1 ENCODING_8BIT
Bit7...bit4: 如果这四位为1100, 1101 or 1110
1110 ENCODING_16BIT(UCS-2)
1100/1101 ENCODING_7BIT
bit1...bit0: 如果有Class
00 CLASS_0
01 CLASS_1
10 CLASS_2
11 CLASS_3
所以,这个PDU包数据是8Bit编码,没有Class类型。
现在PDU扫描到了红色处(绿色部分已经扫描结束):
0891683108200105f04408a0015608860104216092902512236e0605040b8423f0120601ae02056a
0045c60c033231312e3133362e3130372e37382f646f776e2e7068703f703d413063303026733d38
3500080103e68e8ce68fa1e882a1e5b882e58588e69cbaefbc8ce6aca2e8bf8ee4bdbfe794a8e689
8be69cbae8af81e588b8e38082000101
6.TP-Service-Centre-Time-Stamp
短信中心下发的时间戳,这个编码和长度固定
21609290251223
21 Year: 12
60 Month: 06
92 Day: 29
90 Hour: 09
25 Minute: 52
12 Second: 21
23 TimeZone Byte
时区同样高4bit在低位,低4bit在高位
Bit3为时区+/-标志位
计算的结果为1/4时区
0x23 = 0010 0011
Bit3: sign symbol
0 +
1 -
0010 x011 -> x011 0010 = 0011 0010 = 32 [quarter-hour]
TimeZone: + 32 / 4 = +8
所以,得到时间戳为:12-06-29 09:52:21 GMT+8
现在PDU扫描到了红色处(绿色部分已经扫描结束):
0891683108200105f04408a0015608860104216092902512236e0605040b8423f0120601ae02056a
0045c60c033231312e3133362e3130372e37382f646f776e2e7068703f703d413063303026733d38
3500080103e68e8ce68fa1e882a1e5b882e58588e69cbaefbc8ce6aca2e8bf8ee4bdbfe794a8e689
8be69cbae8af81e588b8e38082000101
7. UserDataHeader – UDH
UserDataLength: 长度包含UDH和UD,但不包含这个字节本身
0x6E = 110
UserDataHeaderLength: 该长度不包含这个字节本身
0x06 = 6
UserDataHeader: 05040b8423f0
UDH中可能有多段,所以要不断解析,直到UDH结束
UDH每段含义开头都有个id做标示,接下来是后面具体含义的数据的字节个数,然后才是具体数据
id - 0x05
0x00 ELT_ID_CONCATENATED_8_BIT_REFERENCE
0x08 ELT_ID_CONCATENATED_16_BIT_REFERENCE
0x05 ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT
0x04 ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT
0x24 ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT
0x25 ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT
length: 4
dest port: 0b84 -> 0x0B84 = 2948
2948 for WAP_PUSH
src port: 23f0 -> 0x23F0
PDU是用端口来识别具体业务的,比如这个PDU的目的端口是2948,就是WAP PUSH的PDU封装。
另外,如果还是长SMS,UDH中还会有长SMS拼接所需要的信息,UDH中就有了多重的含义。
现在PDU扫描到了红色处(绿色部分已经扫描结束):
0891683108200105f04408a0015608860104216092902512236e0605040b8423f0120601ae02056a
0045c60c033231312e3133362e3130372e37382f646f776e2e7068703f703d413063303026733d38
3500080103e68e8ce68fa1e882a1e5b882e58588e69cbaefbc8ce6aca2e8bf8ee4bdbfe794a8e689
8be69cbae8af81e588b8e38082000101
现在, PDU封装的基本信息已经解析完毕,剩下的是UserData,也已经区分出具体的业务,可以交给具体业务模块去解析。
二、多条SMS PDU的封装
因为单条SMS长度的限制,一条长SMS的发送是拆分成多条SMS发送的,接收时也是多条接收,然后拼接。
下面实例是分两次接收到的一条长SMS的两个SMS PDU:
PDU[0]
0891683108200105f04405a02125f00004216092717455238c0b05040b8423f000030b0201790601
ae02056a0045c6080c03662e31303038362e636e2f662f736a6678000103e689bee69c8be58f8be3
8081e69fa5e5a4a9e6b094e38081e79c8be5b08fe8afb4e38081e79c8be696b0e997bbe280a6e689
8be69cbae9a39ee4bfa1efbc8ce7ae80e58d95e4bda0e79a84e7949fe6b4bbefbc81e8b5b6e5bfab
e4b88be8bd
PDU[1]
0891683108200105f04405a02125f0000421609271745523220b05040b8423f000030b0202bde4bd
93e9aa8ce6898be69cbae9a39ee4bfa1000101
UserDataHeader里有多SMS的信息,我们就从这里开始分析。
1. UDH之前部分
PDU[0]与PDU[1]的UDH之前的部分完全相同,与前面讲的单条SMS PDU的封装也相同,所以这里不再赘述这部分的解析。
2. UserDataHeader– UDH
UserDataLength:
长度包含UDH和UD,但不包含这个字节本身
长度指的是本PDU中的长度
PDU[0]: 0x8C = 140
PDU[1]: 0x22 = 34
UserDataHeaderLength: 该长度不包含这个字节本身
0x0B = 11
UserDataHeader:
UDH中可能有多段,所以要不断解析,直到UDH结束
UDH每段含义开头都有个id做标示,接下来是后面具体含义的数据的字节个数,然后才是具体数据
PDU[0]: 05040b8423f0 00030b0201
PDU[1]: 05040b8423f0 00030b0202
id - 0x05
0x00 ELT_ID_CONCATENATED_8_BIT_REFERENCE
0x08 ELT_ID_CONCATENATED_16_BIT_REFERENCE
0x05 ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT
0x04 ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT
0x24 ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT
0x25 ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT
length: 4
dest port: 0b84 -> 0x0B84 = 2948
2948 PORT_WAP_PUSH
src port: 23f0 -> 0x23F0
这段说明这是WAP PUSH的PDU封装
id - 0x00
length: 03
ConcatRef.refNumber: 0B
ConcatRef.msgCount: 02
ConcatRef.seqNumber:
PDU[0]: 01
PDU[1]: 02
这段说明这是长SMS的分拆出来的PDU封装包:
refNumber标识是属于哪个长SMS,分拆出来的各个分拆包都有相同的refNumber
msgCount长SMS分拆出来的包的个数
seqNumber指示到达的该包在各个分拆包中的顺序:取值1.. msgCount
因为分拆出来的包到达接收端的顺序不一定是按次序的,所以拼接时,要按照这个顺序。
3. UserData
这是一条长SMS拆分出的两条,所以UserData要按seqNumber次序拼接起来。
PDU[0]
0891683108200105f04405a02125f00004216092717455238c0b05040b8423f000030b0201790601
ae02056a0045c6080c03662e31303038362e636e2f662f736a6678000103e689bee69c8be58f8be3
8081e69fa5e5a4a9e6b094e38081e79c8be5b08fe8afb4e38081e79c8be696b0e997bbe280a6e689
8be69cbae9a39ee4bfa1efbc8ce7ae80e58d95e4bda0e79a84e7949fe6b4bbefbc81e8b5b6e5bfab
e4b88be8bd
PDU[1]
0891683108200105f04405a02125f0000421609271745523220b05040b8423f000030b0202bde4bd
93e9aa8ce6898be69cbae9a39ee4bfa1000101
把PDU[0]和PDU[1]中的红色的UserData拼接起来,得到完整的UserData。
790601ae02056a0045c6080c03662e31303038362e636e2f662f736a6678000103e689bee69c8be5
8f8be38081e69fa5e5a4a9e6b094e38081e79c8be5b08fe8afb4e38081e79c8be696b0e997bbe280
a6e6898be69cbae9a39ee4bfa1efbc8ce7ae80e58d95e4bda0e79a84e7949fe6b4bbefbc81e8b5b6
e5bfabe4b88be8bdbde4bd93e9aa8ce6898be69cbae9a39ee4bfa1000101
至此,完整的UserData已经得到,在UDH中也已经区分出具体的业务,可以交给具体业务模块去解析。
三、小结
Delivery SMS PDU中可以解析出:Service Centre(可无)、有无UDH、PDU类型的识别、发送方号码、TP-PID、编码格式、Class类型(可无)、时间戳、UDH(可无。含:UserData长度、UserDataHeader长度,可能有端口号或Concat信息,等)以及包含具体业务数据的UserData。
关于UserData中具体WAP PUSH业务的封装格式,在后续文章《WAP PUSH解析(2)——WSP以及WBXML编码》和《WAP PUSH解析(3)——Android中实现》中解读。
分享到:
相关推荐
短信PDU编码,直接填入接收者号码,及短信内容可生成PDU编码 短信PDU解码,可解析接收到的编码格式为PDU的短信内容
sms中的pdu格式编码,用的的可以看下
详细的PDU码教程及解析,学习手机通信、短信发送必备资料
sms的pdu编码规则
SmS PDU编码解码 代码 UNICODE2SMS 是一个非常好的示例程序, VC++ 框架
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十三项组成...
可以应用单片机,手机,PC通信软件开发使用,用于TD-SCDMA, GSM, 模块短信开发使用,支持编码和解码,字符集包含bit7,bit8,UNICODE格式
SMS with the SMS PDU-mode
短信pdu编码解码工具,支持中文!
短信PDU编码规则,讲的很详细,希望对你的项目有帮助
简介:PDU编码协议简介 目前,发送短消息常用Text和PDU(Protocol Data Unit,协议数据单元)模式。使用Text模式收发短信代码简单,实现起来十分容易,但最大的缺点是不能收发中文短信;而PDU模式不仅支持中文短信,也...
PDU编码格式,内容较详细。 PDU编码格式,内容较详细。
包含PDU编码、解码的一些算法
软件介绍: SMS PDU TOOLS V1.0支持中国移动和中国联通短消息,只需输入手机号码和短消息内容,即可生成相应的PDU数据包,并显示TPDU和PDU长度。非常方便短信 SMS 开发时使用。
PDU短信的编程,做成标准类,三种编码和解码都有
SMS PDU格式短信发送接收参考手册,很好用用的短信开发指南
PDU格式与汉字自动转换,方便快捷 PDU格式与汉字自动转换,方便快捷
sms pdu 转换工具! sms pdu 转换工具! sms pdu 转换工具! (无源码)
有关SMS短信的PDU编码,用于安卓等相应系统开发时的参考文档,尤其是在写有关短信的应用时的参考文档
本程序实现了用java语言控制串口,采用pdu编码对数据进行编解码。最终分别实现了收发短信的功能。