CMPP协议对长短信的支持(C#版)
1。CMPP3.0 超长短信
http://59905.blog.spforum.net/26058.html
1、长短信息:是指超过70个汉字,140个字节的信息内容。最近在做一个某地市公司运营商的GPRS导引项目的时候,运营商要求将对用户的提示短信息(超过140个字节)发送到用户手机,在用户的手机上一次全显示。
上网搜索了一些相关的资料,现在将实现总结如下:
一、CMPP协议相关字段分析(在此只讲发长短信相关的cmpp_submit消息,cmpp的其他内容的请参考《中国移动互联网短信网关接口协议(V3.0.0).doc》
字段名 | 字节数 | 属性 | 描述 |
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_UserType为3时该值有效,当Fee_UserType为0、1、2时该值无意义。 |
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 | 信息格式: 0:ASCII串; 3:短信写卡操作; 4:二进制信息; 8:UCS2编码; 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流程不使用该字段。 |
红 色部分表示发长短信要更改的字段
洋红色部分表示发长短信可以更改或者不更改的字段
(以下资料参考:http://publishblog.blogdriver.com/zeroliu/1234594.html)
在cmpp协议里,CMPP_SUBMIT消息定义中有相应的参数配置:
TP_udhi:0代表内容体里不含有协议头信息1代表内容含有协议头信息(长短信,push短信等都是在内容体上含有头内容的)当设置内容体包含协议头,需要根据协议写入相应的信息,长短信协议头有两种:
6位协议头格式:050003XXMMNN
byte1:05,表示剩余协议头的长度
byte2:00,这个值在GSM03.40规范9.2.3.24.1中规定,表示随后的这批超长短信的标识位长度为1(格式中的XX值)。
byte3:03,这个值表示剩下短信标识的长度
byte4:XX,这批短信的唯一标志,事实上,SME(手机或者SP)把消息合并完之后,就重新记录,所以这个标志是否唯
一并不是很重要。
byte5:MM,这批短信的数量。如果一个超长短信总共5条,这里的值就是5。
byte6:NN,这批短信的数量。如果当前短信是这批短信中的第一条的值是1,第二条的值是2。
例如:050003390201
7位的协议头格式:060804XXXXMMNN
byte1:06,表示剩余协议头的长度
byte2:08,这个值在GSM03.40规范9.2.3.24.1中规定,表示随后的这批超长短信的标识位长度为2(格式中的XX值)。
byte3:04,这个值表示剩下短信标识的长度
byte4-5:XXXX,这批短信的唯一标志,事实上,SME(手机或者SP)把消息合并完之后,就重新记录,所以这个标志是否唯一并不是很重要。
byte6:MM,这批短信的数量。如果一个超长短信总共5条,这里的值就是5。
byte7:NN,这批短信的数量。如果当前短信是这批短信中的第一条的值是1,第二条的值是2。
例如:06 08 04 00 39 02 01二. 实现代码(C#)
byte[] messageUCS2 = Encoding.BigEndianUnicode.GetBytes(MtMsg);
intmessageUCS2Len=messageUCS2.Length;
intmaxMessageLen=140;
if(messageUCS2Len>maxMessageLen)
{
intmessageUCS2Count=messageUCS2Len/(maxMessageLen-6)+1;
//长短信分为多少条发送
byte[]tp_udhiHead=newbyte[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(inti=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发长短信
1、TP_udhi设置为 0x01
2、Msg_Content 按TP_udhi协议填写6字节或者7字节的TP_udhi协议头然后加上经过USC2编码的消息内容。由TP_udhi协议头和消息内容体组成的 Msg_Content总长度不能超过140个字节
3、 Msg_Fmt 设置为 0x08 UCS2编码;
4、Pk_total和Pk_number 可以不设置,如果要设置,就要分别跟TP_udhi的MM和NN字段一致