1.1. 基本知識
短信開發指通過串口 at 命令驅動短信貓進行短信發送和接收操作。
在 java 中 主要使用 javax.comm 包進行開發,
sun 公司網上地址 : http://java.sun.com/products/javacomm/
使用工具 : windows 自帶超級終端
短信貓操作分為三種模式: block,pdu 和 Text
短信傳送有三種編碼: 7 位, 8 位, UniCode
at 命令 ,at 命令是驅動短信設備的標準工業命令,除了業界的標準之外,每個廠商可能會對其進行擴展,不過一般來說,標準命令應該夠用,這次用的是西門子 tc35i ,有專門的 at 命令文檔。
1.1.1. 相關文檔
Gsm03.38 規范: Alphabets and language-specific information 著重介紹短信發送中對字符集的控制部分
Gsm03.40 規范: Technical realization of the Short Message Service (SMS) Point-to-Point (PP) 詳細介紹各種不同短信的不同實現
Gsm07.05 規范: Use of Data Terminal Equipment - Data Circuit terminating;Equipment (DTE - DCE) interface for Short Message Service (SMS) and Cell Broadcast Service (CBS) ,介紹 at 的一些控制命令。
Gsm07.07 規范:著重介紹 at 的短信相關命令,可以說是 at 的 sms 規范。
1.1.2. Block 模式
Block 模式基本已經被 pdu 模式取代,沒有具體研究
1.1.3. Text 模式
Text 模式比較簡單,但是支持的設備不是很全,而且對于中文似乎有些問題,在金笛的網站技術資料中似乎提到了一句不能實現中文。
AT + CGMF=1<CR>
AT + CGMS= “ 13605696031 ” ,129<CR>
>Hello World!<^Z>
1.1.4. Pdu 模式
pdu 編碼主要包括兩個主要的部分,一是 pdu 串的整體數據格式,分別因為發送信息串和接收信息串而有區別,二是 pdu 中文本部分的編碼,分別因為字符集而不同。
我們也可以這樣來理解這個 pdu 編碼的格式, sms 相當于一個協議棧,最簡單的協議棧:
根據 gsm03.40 規范, sms 協議包括以下幾層:
1、 SM-AL :應用層。這個部分就是數據部分。
2、 SM-TL :傳輸層。我們可以清楚的看到這里描述了主要的短信內容,包括發送號碼,接收號碼,信息類型,編碼,數據報長度等等,這也是我們編程主要要面對的問題。
3、 SM-RL :中繼層。這個指的是短信在網關之間中繼需要的協議。
4、 SM-LL: 鏈路層。
從上述描述中我們可以清楚的看到,我們編程主要集中于傳輸層。
PDU 串的用戶信息 (TP-UD) 段最大容量是 140 字節,所以在這三種編碼方式下,可以發送的短消息的最大字符數分別是 160 、 140 和 70 。這里,將一個英文字母、一個漢字和一個數據字節都視為一個字符。
1.2. SMS 用戶數據的編碼方法
1.2.1. 英文 7 位編碼
圖片不能正確顯示
這是 gsm 的默認編碼方式
由于這樣的移位,我們可以看到我們能發的最多英文字符等于: 140*8/7 = 160 。
1.2.2. 數據 8 位編碼
8-bit 編碼通常用于發送數據消息,比如圖片和鈴聲等;
1.2.3. 中文 pdu 編碼
發送中文時,必須用 UCS2 ( utf-16 )進行編碼,最多可以發 140/2 = 70 個漢字。
UniCode 編碼轉換也比較簡單,以中文為例,一個中文字符是兩個字節,直接對高位字節和低位字節進行十六進制轉換就可以了。如“歡迎”, UniCode 編碼是 6B22 8FCE ,這同時也就是轉換的結果,如果發送的串中有英文字符,那么在前面補全 00 ,以保證一個字符對應兩個字節。
1.2.4. Wap-push 中的中文編碼
做 wap-push 短信的時候有些問題了,開始的時候也按照 Unicode 編碼處理,總是失敗,后來才發現,有個編碼字段設為了 uft-8 ,所以在這種情況下,還是可以出現其他編碼方式的。
1.3. 短信報頭分析
1.3.1. 短信類型
詳細請參考 gsm 0438 規范和 gsm0440 規范,里面有詳細的關于各種短消息類型的描述。
在 sms 中到底支持多少種類型的短信,短信類型由什么進行控制,這是我們在這里需要著重介紹的問題。
在傳輸層來分,一共有六大短信類型: SMS-DELIVER , SMS-DELIVER-REPORT , SMS-SUBMIT , SMS-SUBMIT-REPORT , SMS-STATUS-REPORT , SMS-COMMAND ,這六種短信類型,由短信中心地址后的第一個字節的最低兩位控制。
bit1
|
bit0
|
Message type
|
0
|
0
|
SMS-DELIVER (in the direction SC to MS)
|
0
|
0
|
SMS-DELIVER REPORT (in the direction MS to SC)
|
1
|
0
|
SMS-STATUS-REPORT (in the direction SC to MS)
|
1
|
0
|
SMS-COMMAND (in the direction MS to SC)
|
0
|
1
|
SMS-SUBMIT (in the direction MS to SC)
|
0
|
1
|
SMS-SUBMIT-REPORT (in the direction SC to MS)
|
1
|
1
|
Reserved
|
也就是說,每個短信在短信中心地址之后的第一個字節的最低兩位是至關重要的。他決定了如何讀這條短信(結合是發送的,還是接收的)
1.3.2. 地址編碼
短信發送中都會涉及到短信地址的問題,他們的編碼規則是一致的 , 簡單來說就是 BCD8421碼編碼。
如: 08 91 683108501505F 0 ,
08 :地址長度,(號碼類型 + 號碼長度) /2 的十六進制表示
91 :號碼類型
683108501505F 0 :號碼,實際號碼應為: 8613805515500 ,號碼處理方法為 , 如果為 +86 開始 , 將 + 號去掉 , 然后判斷是否為偶數 , 不是在末尾補 F, 然后將奇數位和偶數位互換
1.3.3. TP-DCS( 數據編碼格式 )
這個字節比較特殊,表明整個短信的字符編碼,數據內容等信息。詳細說明參考 gsm03.38 規范。
1.3.4. 第一個字節
Pdu 編碼的第一個字節比較有意思,這個字節會根據六種不同的短信按位有不同的意思,拿句專業一點的話來說,叫 bitmask. 用圖來大概描述一下,詳細參考 gsm0340 的 9.2.3 段。
位數
|
MSG_Deliever
|
MSG_SUBMIT
|
7
|
TP_RP (回復地址)
|
TP_RP
|
6
|
TP_UDHI (數據報頭)
|
TP_UDHI
|
5
|
TP_SRI (需要回復)
|
TP_SRR (請求回復)
|
4
|
|
TP_VPF( 時間格式 )
|
3
|
|
2
|
TP_MMS (多條短信標志, 1 為無, 0 為有)
|
TP_RD( 拒絕重復標志 )
|
1 , 0
|
TP_MTI (短信類型)
|
TP_MTI
|
常見值
|
04 ,正常收到, 44 ,有報頭短信
|
11 ,正常發送, 51 ,有報頭短信
|
1.3.5. TP-PID (協議標識)
在這個里面還有一個字節比較特殊,就是協議標識。
一般都是 00 ,表示點到點的標準短信。
1.3.6. 超長短信
參考 gsm0340 的 9.2.3 .24TP_UD 部分,這個部分中間的一種情況就是描述超長短信的處理。
長短信關鍵涉及一個數據報頭的問題,數據報頭由“長度”和多個“數據元素”組成。
1.3.7. Wap-push 短信
WAP 的推送協議中定義了服務指示( SI : Service Indication )和服務加載( SL : Service Load )兩項服務,以給用戶和網絡運營者更多的選擇。服務指示是將新信息的指示和相關的通用資源標識符( URI )推送給用戶,由用戶選擇是立即處理信息還是以后處理。服務加載是將一項服務的 URI 推送給用戶,然后客戶端自動地使用 PULL 技術根據該 URI 啟動服務。兩種服務的區別在于用戶是否介入推送信息的處理過程。 SL 對推送信息的處理對用戶來說是透明的,而 SI 則在指示用戶的同時,請用戶對隨后的處理做出選擇。
PUSH 可以將某一站點或某一業務的鏈接通過短信發送到支持 WAP PUSH 功能的手機上,這樣用戶只需要閱讀這條短信,打開短信中的鏈接,就可以直接訪問業務了。因此, WAP PUSH 實現了短信和 WAP 業務的結合,節省了用戶尋找業務的時間,方便用戶直接找到并使用自己喜歡的業務。
Wap-push 短信的核心不同之處就在于:
1、 含有數據報頭,也就是 TP_UDHI 位為 1 ,一般來說 pdu 的第一個字節發送時為 51 ,接收時為 44 。
2、 TP_DSC 字節不同,一般為 F5 ,表明字符集為 8 位,短信類型為 Class 1; 詳細解釋參看 gsm03.38 的第四章。
1.4. 編碼示例
1.4.1. 發送信息的 PDU 串:
用手機寫一條短信息,發送手機號碼為 13605696031 ,信息內容為“ Hello World! ”。通過執行 AT + CMGL=2 可以讀出此條信息。
AT + CMGL=2 { 讀未發短信息 }
+ CMGL: 1,2,,24 {1 表示信息個數, 2 表示未發信息, 24 表示信息總容量 }
08 91 683108501505F0 11 00 0B 81 3106656930F1 0000FF 0B E8329BFD06DDDF723619
OK
下面分析這條信息:
08
|
短信息中心地址長度。(短信息中心號碼類型 + 短信息中心號碼長度 /2 的十六進制表示)
|
91
|
短信息中心號碼類型, 91 是 TON/NPI 。 TON/NPI 遵守 International/E.164 標準,指在號碼前需加‘+’號 ; 此外還可有其他數值,但 91 最常用。
|
683108501505F 0
|
短信息中心號碼,是所使用的服務中心地址。由于位置上略有處理,實際號碼應為: 8613805515500( 字母 F 意指長度減 1), 這是作者所在地 GSM 短信息中心的號碼。 ( 號碼處理方法為 , 如果為 +86 開始 , 將 + 號去掉 , 然后判斷是否為偶數 , 不是在末尾補 F, 然后將奇數位和偶數位互換 )
|
11
|
文件頭字節 (header byte, 是一種 bitmask) 。這里 11 指正常地發送短信息。
|
00
|
信息參考號。( TP-MR )
|
0D
|
被叫號碼長度。被叫號碼長度的十六進制表示。
|
81
|
被叫號碼類型。
|
3106656930F 1
|
被叫號碼,也經過了移位處理,實際號碼為 13605696031 。
|
00
|
協議標識 (TP-PID), 是普通 GSM 類型,點到點方式
|
00
|
用戶信息編碼方式 (TP-DCS) , 7-bit 編碼( 08 : UCS2 編碼)
|
FF
|
有效期 (TP-VP), 短信的有效時間
|
0B
|
短信息長度
|
E8329BFD06DDDF723619
|
短信息內容“ Hello World! ”。
|
1.4.2. 接受信息的 PDU 串
讀取以上發送出來的短信,可以收到如下信息 , 接受到來自 13600554267 的“歡迎“ PDU 串為: 0891683108503705F0040D91683106504562F7000830507001021500046B228FCE 。而接受到的“歡迎“ PDU 串為:
0891683108503705F0040D91683106504562F70000305070010201000AE8329BFD4697D9EC37 。對以上的 PDU 串分析如下表:
段
|
含義
|
說明
|
08
|
SMSC 地址信息的長度
|
共 8 個八位字節 ( 包括 91)
|
91
|
SMSC 地址格式 (TON/NPI)
|
用國際格式號碼 ( 在前面加 ‘+’)
|
683108503705F 0
|
SMSC 地址
|
8613800573500 ,補 ‘F’ 湊成偶數個
|
04
|
基本參數 (TP-MTI/MMS/RP)
|
接收,無更多消息,有回復地址,如果為 00 ,就沒有以下關于回復地址的三個段
|
0D
|
回復地址數字個數
|
共 13 個十進制數 ( 不包括 91 和 ‘F’)
|
91
|
回復地址格式 (TON/NPI)
|
用國際格式號碼 ( 在前面加 ‘+’)
|
683106504562F 7
|
回復地址 (TP-RA)
|
8613600554267 ,補 ‘F’ 湊成偶數個
|
00
|
協議標識 (TP-PID)
|
是普通 GSM 類型,點到點方式
|
08
|
用戶信息編碼方式 (TP-DCS)
|
UCS2 編碼(即中文)
|
30507001021500
|
時間戳 (TP-SCTS)
|
2003-3-12 08:36:45 +8 時區
|
04
|
用戶信息長度 (TP-UDL)
|
實際長度 4 個字節
|
6B228FCE
|
用戶信息 (TP-UD)
|
“ 歡迎 !”
|
1.4.3. 超長短信
所謂超長短信不同的地方無非就是數據報文需要有個拼接的過程,這個詳細可以參考 gsm03.40 的 9.2.3 .24.1 段。下面是個例子,表明的是短信的第一條和第二條。
第一條
0891683108100005F0
|
SMSC 地址
|
44
|
有協議頭標志
|
0D91683118216553F6
|
回復地址
|
0008
|
TP-PID , TP-DCS
|
60403011142423
|
時間戳 (TP-SCTS)
|
8C
|
用戶信息長度 (TP-UDL)
|
05
|
協議頭的長度
|
00
|
標志這是個分拆短信
|
03
|
分拆數據元素的長度
|
39
|
唯一標志(用于把兩條短信合并)
|
02
|
一共兩條
|
01
|
這是第一條
|
4E8C96F64E005B9A4
F1A597D597D597D76
8465F 665F 665F 695F 4
4E0D597D597D597D7684 60254F1A4E8654754F604 E5F4E0D898157284E006 B21751F76EE8FDB665A 70B954275417662F4E00 4E2A4E1C5F20897F6211 4E0D662F62117231597D 4E86541754758BBE7F6E 597D597D554A51765B83 662F554A5475547554754 F607684547562A4
|
數據內容
|
第二條
0891683108100005F0
|
SMSC 地址
|
44
|
有協議頭標志
|
0D91683118216553F6
|
回復地址
|
0008
|
TP-PID , TP-DCS
|
60403011145423
|
時間戳 (TP-SCTS)
|
26
|
用戶信息長度 (TP-UDL)
|
05
|
協議頭的長度
|
00
|
標志這是個分拆短信
|
03
|
分拆數據元素的長度
|
39
|
唯一標志(用于把兩條短信合并)
|
02
|
一共兩條
|
02
|
這是第二條
|
81EA4ECE524D5C317761 7740542754755475007A0 07A006C0076006C006F0 07A
|
數據
|
1.4.4. Wap-push 短信
發送的 pdu ,關于 wap-push 短信中間的 wbxml 該如何轉變和編碼,請參考 WAP Service Indication 規范。
0891683108100005F0
|
SMSC 地址
|
51
|
有協議頭標志
|
00
|
TP_MR 消息基準值
|
0D91683118216553F6
|
回復地址
|
00
|
TP-PID
|
F5
|
TP-DCS
|
A7
|
有效期 TP-VP
|
85
|
用戶信息長度( TP-UDL )
|
0B
|
WAP PUSH 頭部的總長度
|
05
|
協議頭的長度
|
00
|
標志這是個分拆短信
|
03
|
分拆數據元素的長度
|
03
|
唯一標志(用于把兩條短信合并)
|
01
|
一共一條
|
01
|
這是第一條
|
05040B8423F0
|
表示接下來是一個 WAP PUSH
|
29060603AE81EA8DCA
|
WSP
|
02
|
標記位
|
05
|
-//WAPFORUM//DTD SI 1.0//EN
|
6A
|
UTF-8
|
00
|
標記開始
|
45
|
<si>
|
C6
|
<indication
|
08
|
<action=signal-high>
|
0C
|
href="http://
|
03
|
字符串開始
|
3231312e3133362e31353 32e33302f776170707573 682f70757368496e64657 82e6a73703f7075736849 643d3035303531313134 313630353231
|
URL
|
00
|
URL 字符串結束
|
01
|
>
|
03
|
內容描述字符串開始
|
E8AFB7E782B9E587BB E4BBA5E4B88BE993B EE68EA5E88EB7E58F 96E5BDA9E4BFA1E5 8685E5AEB9
|
內容描述字符串
|
00
|
內容描述字符串結束
|
01
|
</si>
|
01
|
</indication>
|