WAP PUSH解析(1)——SMS PDU编码
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中實現》中解讀。
?
?
總結
以上是生活随笔為你收集整理的WAP PUSH解析(1)——SMS PDU编码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 收集17句经典程序员口头禅
- 下一篇: java 图片阴影_Java 为 PPT