SMPP長短信拆分原理與實現

             短信息收發有關的規範主要包括GSM 03.38、GSM03.40和GSM 07.05。前二者着重描述SMS的技術實現(含編碼方式),後者則規定了SMS的DTE-DCE接口標準(AT命令集)。短信息的收發共有三鍾方式:Block方式, Text方式和PDU方式。Block方式目前很少用;Text方式是純文本方式,可使用不同的字符集,從技術上說也可用於發送中文短信息,但國內手機基本上不支持,主要用於歐美地區;PDU方式被所有手機支持,可以使用任何字符集,這也是手機默認的編碼方式。

             PDU串表面上是一串ASCII碼,由‘0’-‘9’、‘A’-‘F’這些數字和字母組成。它們是8位字節的十六進制數。PDU串不僅包含可顯示的消息本身,還包含很多其它信息,如SMS服務中心號碼、目標號碼、編碼方式等。PDU方式下可以採用三種編碼發送短信息:7bit編碼、8bit編碼和16bit(UCS2)編碼。 

            在《GSM_03.40》規範中明確了一條短信長度爲:

                        140字符:採用8bit編碼

                        160字符:採用7bit編碼

                        70字符:採用16bit編碼

            一般情況下,超長的短信內容一般採用兩種解決方案:一是分多條單獨的短信發送,這樣手機上會收到多條短信,二是通過UDHI機制分多條短信發送,這樣手機上會顯示爲一條按照順序組合在一起的長短信。從實現原理上第一種簡單一些,但是短信到達手機上順序可能會亂序;第二種方案相對較好一些,下面講解下在SMPP協議上如何進行長短信發送。

           發送超長短信,需要做兩件事情:設置TP_udhi的值設置爲1,在消息正文中增加協議頭。協議後可以兩種格式,分別是長度爲6和長度爲7的協議頭。格式如下:  

6位協議頭格式:05 00 03 XX MM NN 
byte 1 : 05, 表示剩餘協議頭的長度 
byte 2 : 00, 這個值在GSM 03.40規範9.2.3.24.1中規定,表示隨後的這批超長短信的標識位長度爲1(格式中的XX值)。 
byte 3 : 03, 這個值表示剩下短信標識的長度 
byte 4 : XX,這批短信的唯一標誌,事實上,SME(手機或者SP)把消息合併完之後,就重新記錄,所以這個標誌是否唯一並不是很重要。 
byte 5 : MM, 這批短信的數量。如果一個超長短信總共5條,這裏的值就是5。 
byte 6 : NN, 這批短信的數量。如果當前短信是這批短信中的第一條的值是1,第二條的值是2。 
例如:05 00 03 39 02 01 

7位的協議頭格式:06 08 04 XX XX MM NN 
byte 1 : 06, 表示剩餘協議頭的長度 
byte 2 : 08, 這個值在GSM 03.40規範9.2.3.24.1中規定,表示隨後的這批超長短信的標識位長度爲2(格式中的XX值)。 
byte 3 : 04, 這個值表示剩下短信標識的長度 
byte 4-5 : XX XX,這批短信的唯一標誌,事實上,SME(手機或者SP)把消息合併完之後,就重新記錄,所以這個標誌是否唯一並不是很重要。 
byte 6 : MM, 這批短信的數量。如果一個超長短信總共5條,這裏的值就是5。 
byte 7 : NN, 這批短信的數量。如果當前短信是這批短信中的第一條的值是1,第二條的值是2。 
例如:06 08 04 00 39 02 01 

           7位協議頭和6位協議頭的區別是,6位協議頭短信的標識字段是1個byte,而7位協議頭短信的標誌字段爲2個byte。大多手機採用6位的協議頭,也就是05 00 03 XX MM NN。 

           基於Logica Open SMPP API做長短信拆分樣例如下:

// 參考《3GPP TS 23.040 V6.8.1 (2006-10).pdf》

// Set UDHI Flag Data.SM_UDH_GSM=0x40
request.setEsmClass((byte) Data.SM_UDH_GSM);

// 設置UDH內容
ByteBuffer ed = new ByteBuffer();
ed.appendByte((byte) 5); // UDH Length
ed.appendByte((byte) 0x00); // IE Identifier
ed.appendByte((byte) 3); // IE Data Length
ed.appendByte((byte) refNum); // Reference Number
ed.appendByte((byte) totalSegments); // Number of pieces
ed.appendByte((byte) i); // Sequence number
StringBuilder builder = new StringBuilder();

// 將短信內容編碼
try {
	ed.appendString(message, encode);
	request.setShortMessageData(ed);
	return request;
} catch (Exception e) {
	
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章