CMPP3.0 長簡訊實現方案

小y發表於2016-07-26

長簡訊息:是指超過70個漢字,140個位元組的資訊內容

一、CMPP協議相關欄位分析

CMPP協議具體部分請參考《中國移動網際網路簡訊閘道器介面協議(V3.0.0.doc

 

CMPP_SUBMIT訊息定義(SP--->SMG

 

欄位名

位元組數

屬性

描述

Msg_Id

8

Unsigned Integer

資訊標識。

Pk_total

1

Unsigned Integer

相同Msg_Id的資訊總條數,從1開始。

Pk_number

1

Unsigned Integer

相同Msg_Id的資訊序號,從1開始。

Registered_Delivery

1

Unsigned Integer

是否要求返回狀態確認報告:

0:不需要;

1:需要。

Msg_level

1

Unsigned Integer

資訊級別。

Service_Id

10

Octet String

業務標識,是數字、字母和符號的組合。

Fee_UserType

1

Unsigned Integer

計費使用者型別欄位:

0:對目的終端MSISDN計費;

1:對源終端MSISDN計費;

2:對SP計費;

3:表示本欄位無效,對誰計費參見Fee_terminal_Id字 段。

Fee_terminal_Id

32

Octet String

被計費使用者的號碼,當Fee_UserType3時該值有效,當Fee_UserType012時該值無意義。

Fee_terminal_type

1

Unsigned Integer

被計費使用者的號碼型別,0:真實號碼;1:偽碼。

TP_pId

1

Unsigned Integer

GSM協議型別。詳細是解釋請參考GSM03.40中的9.2.3.9

TP_udhi

1

Unsigned Integer

GSM協議型別。詳細是解釋請參考 GSM03.40中的9.2.3.23,僅使用1位,右對齊。

Msg_Fmt

1

Unsigned Integer

資訊格式:

0ASCII串;

3:簡訊寫卡操作;

4:二進位制資訊;

8UCS2編碼;

15:含GB漢字。。。。。。

Msg_src

6

Octet String

資訊內容來源(SP_Id)

FeeType

2

Octet String

資費類別:

01:對計費使用者號碼免費;

02:對計費使用者號碼按條計資訊費;

03:對計費使用者號碼按包月收取資訊費。

FeeCode

6

Octet String

資費程式碼(以分為單位)。

ValId_Time

17

Octet String

存活有效期,格式遵循SMPP3.3協議。

At_Time

17

Octet String

定時傳送時間,格式遵循SMPP3.3協議。

Src_Id

21

Octet String

源號碼。SP的服務程式碼或字首為服務程式碼的長號碼, 閘道器將該號碼完整的填到SMPP協議Submit_SM訊息相應的source_addr欄位,該號碼最終在使用者手機上顯示為短訊息的主叫號碼。

DestUsr_tl

1

Unsigned Integer

接收資訊的使用者數量(小於100個使用者)

Dest_terminal_Id

32*DestUsr_tl

Octet String

接收簡訊的MSISDN號碼。

Dest_terminal_type

1

Unsigned Integer

接收簡訊的使用者的號碼型別,0:真實號碼;1:偽碼。

Msg_Length

1

Unsigned Integer

資訊長度(Msg_Fmt值為0時:<160個位元組;其 它<=140個位元組),取值大於或等於0

Msg_Content

Msg_length

Octet String

資訊內容。

LinkID

20

Octet String

點播業務使用的LinkID,非點播類業務的MT流程不使用該欄位。

 

紅色部分表示髮長簡訊要更改的欄位

洋紅色部分表示髮長簡訊可以更改或者不更改的欄位

 

cmpp協議裡,CMPP­_SUBMIT訊息定義中有相應的引數配置:   

  1. TP_udhi 0代表內容體裡不含有協議頭資訊 1代表內容含有協議頭資訊(長簡訊,push簡訊等都是在內容體上含有頭內容的)當設定內容體包含協議頭,需要根據協議寫入相應的資訊,長簡訊協議頭有兩種:

 

  • 6位協議頭格式:05 00 03 XX MM NN

a) byte 1 : 05, 表示剩餘協議頭的長度

b) byte 2 : 00, 這個值在GSM 03.40規範9.2.3.24.1中規定,表示隨後的這批超長簡訊的標識位長度為1(格式中的XX值)。

c) byte 3 : 03, 這個值表示剩下簡訊標識的長度

d) byte 4 : XX,這批簡訊的唯一標誌,事實上,SME(手機或者SP)把訊息合併完之後,就重新記錄,所以這個標誌是否唯一併不是很 重要。

e) byte 5 : MM, 這批簡訊的數量。如果一個超長簡訊總共5條,這裡的值就是5

f) byte 6 : NN, 這批簡訊的數量。如果當前簡訊是這批簡訊中的第一條的值是1,第二條的值是2

例如:05 00 03 39 02 01

 

  • 7 位的協議頭格式:06 08 04 XX XX MM NN

a) byte 1 : 06, 表示剩餘協議頭的長度

b) byte 2 : 08, 這個值在GSM 03.40規範9.2.3.24.1中規定,表示隨後的這批超長簡訊的標識位長度為2(格式中的XX值)。

c) byte 3 : 04, 這個值表示剩下簡訊標識的長度

d) byte 4-5 : XX XX,這批簡訊的唯一標誌,事實上,SME(手機或者SP)把訊息合併完之後,就重新記錄,所以這個標誌是否唯一併不是很重要。

e) byte 6 : MM, 這批簡訊的數量。如果一個超長簡訊總共5條,這裡的值就是5

f) byte 7 : NN, 這批簡訊的數量。如果當前簡訊是這批簡訊中的第一條的值是1,第二條的值是2

例如:06 08 04 00 39 02 01    

二、實現程式碼(C#)

   byte[] messageUCS2 = Encoding.BigEndianUnicode.GetBytes(MtMsg);

            int messageUCS2Len = messageUCS2.Length;

            int maxMessageLen = 140;

            if (messageUCS2Len > maxMessageLen)

            {             

                int messageUCS2Count = messageUCS2Len / (maxMessageLen - 6) + 1;

                //長簡訊分為多少條傳送

                byte[] tp_udhiHead = new byte[6];

                tp_udhiHead[0] = 0x05;

                tp_udhiHead[1] = 0x00;

                tp_udhiHead[2] = 0x03;

                tp_udhiHead[3] =//0x0A;

                tp_udhiHead[4] = (byte)messageUCS2Count;

                tp_udhiHead[5] = 0x01;

                //預設為第一條

                for (int i = 0; i < messageUCS2Count; i++)

                {

                    tp_udhiHead[5] = (byte)(i + 1);

                    byte[] msgContent;

                    if (i != messageUCS2Count - 1)

                    {

                        //不為最後一條

                        msgContent =BIConvert.byteAdd(tp_udhiHead, messageUCS2, i * (maxMessageLen - 6), (i + 1) * (maxMessageLen - 6));

                    }

                    else

                    {

                        msgContent = BIConvert.byteAdd(tp_udhiHead, messageUCS2, i * (maxMessageLen - 6), messageUCS2Len);

                    }                 

                }

            }

 

 

三、總結

以上是移動CMPP中長簡訊的實現方法,在聯通、電信簡訊協議中,實現方法一樣。

 

移動CMPP協議長簡訊方案:

 

  1. Msg_Fmt = 8 ; 
    Tp_Udhi = 1;
  2. 可採用6位元組協議頭,也可採用7位元組協議頭,實測都通過。 
    • 6位元組協議頭: 
      • MsgContent的前三個位元組為:0x05, 0x00, 0x03(0x05表示後面還有5位元組,0x03表示後面還有3位元組)
      • 第四個位元組為批號,合成同條長簡訊的小簡訊填一樣的值即可。(同時給同個號碼發多條長簡訊的要分不同長簡訊填寫);
      • 第五個位元組為Pk_total的值,即這批簡訊的總條數。
      • 第六個位元組為Pk_number的值,即這條簡訊在長簡訊中的序號,從1開始。。
    • 7位元組協議頭: 
      • MsgContent的前三個位元組為:0x06, 0x08, 0x04(0x06表示後面還有6位元組,0x04表示後面還有4位元組)
      • 第四、五個位元組為批號,合成同條長簡訊的小簡訊填一樣的值即可。(同時給同個號碼發多條長簡訊的要分不同長簡訊填寫);
      • 第六個位元組為Pk_total的值
      • 第七個位元組為Pk_number的值
  3. MsgContent 在第6或7位元組後加上要傳送的簡訊內容,記得要UCS2編碼的哦。
  4. Pk_total和Pk_number 可以不設定,如果要設定,就要分別跟TP_udhi的MM和NN欄位一致

 

聯通SGIP1.2協議長簡訊方案

 

只測試了6位元組協議頭的,方法與以上移動使用的6位元組協議頭一樣。 
MessageCoding= 8 ; 
Tp_Udhi = 1; 
MessageContent前三個位元組為:0x05, 0x00, 0x03 
第四個位元組為批號; 
第五個位元組為這批簡訊的總條數; 
第六個位元組這條簡訊在長簡訊中的序號,從1開始。 
3、MessageContent在第6位元組後加上要傳送的簡訊內容的UCS2編碼

 

電信SMGP3協議長簡訊方案:

 

    1. 設定tlv欄位TP_udhi為0x01,表示訊息內容裡面包含訊息頭(也就是說含長簡訊頭)
    2. 內容前面需要增加6個欄位

      • 位元組一:包頭長度,固定填寫0x05;
      • 位元組二:包頭型別標識,固定填寫0x00,表示長簡訊;
      • 位元組三:子包長度,固定填寫0x03,表示後面三個位元組的長度;
      • 位元組四到位元組六:包內容:
      • 位元組四:長訊息參考號,每個SP給每個使用者傳送的每條參考號都應該不同,可以從0開始,每次加1,最大255,便於同一個終端對同一個SP的訊息的不同的長簡訊進行識別;
      • 位元組五:本條長訊息的的總訊息數,從1到255,一般取值應該大於2;
      • 位元組六:本條訊息在長訊息中的位置或序號,從1到255,第一條為1,第二條為2,最後一條等於第四位元組的值。
    3. 例子: 
      05 00 03 00 02 01 
      05 00 03 00 02 02

    4. 你還需要設定PkTotal和PkNumber 
      這個欄位如果不設定並不影響使用者手機對簡訊的拼裝,但是會影響ismp的健權和計費,一組pktotal pknumber裡面的資料ismp是當一條簡訊健權和計費。

 

提綱

1 物聯網資料卡系統原始碼——前篇

1.1 物聯網技術架構圖

1.2 物聯網的主要應用領域

1.3 物聯網感測器61個應用領域

1.4 物聯網常見通訊協議梳理

2 物聯網資料卡系統原始碼——通訊模組

2.1 通訊模組整體概述

2.2 協議封裝和實現

2.3 長簡訊

2.4 粘包的處理

2.5 物聯網通訊與普通簡訊通訊的區別和要注意的地方

3 物聯網資料卡系統原始碼——Windows服務模組

3.1 Windows服務模組概述

3.2 Windows服務模組實現

3.3 高併發回撥處理

3.4 部署安裝

相關文章