簡訊息收發有關的規範主要包括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=0x40request.setEsmClass((byte) Data.SM_UDH_GSM);// 設定UDH內容ByteBuffer ed = new ByteBuffer();ed.appendByte((byte) 5); // UDH Lengthed.appendByte((byte) 0x00); // IE Identifiered.appendByte((byte) 3); // IE Data Lengthed.appendByte((byte) refNum); // Reference Numbered.appendByte((byte) totalSegments); // Number of piecesed.appendByte((byte) i); // Sequence numberStringBuilder builder = new StringBuilder();// 將簡訊內容編碼try {ed.appendString(message, encode);request.setShortMessageData(ed);return request;} catch (Exception e) {}