CMPP2.0 协议SP端的·NET开发

 

内容简介:本文介绍了CMPP2.0协议SP端.net实现需要注意的问题,并提供解决方案和参考意见,对CMPP协议做一个解读参考。

关键字:CMPP 2.0 SMS ISMG Socket 线程 线程同步 .Net事件模型

一、CMPP协议简介

中国移动通信互联网短信网关接口协议(China Mobile Peer to Peer CMPP),是中国移动梦网内部各SMS参与节点相互交换SMS的官方协议。作为梦网的参与方,移动梦网的增值服务商(Service Provider SP )要按照此协议规范实现SP的部分,才可以将自己的短信通过移动的GSM网络的数据通道传输到最终手机用户上。

实际上,协议规范了3个方面的内容:

。SP与移动的互联网短信网关(Internet Short Message Gateway,ISMG)之间的接口协议

。ISMG之间的接口协议(譬如移动各省、市之间的短信息交换通过ISMG之间进行)

。ISMG与汇接网关(Gateway Name Server GNS,类似互联网上的DNS服务器)之间的接口协议,譬如跨省之类的短信需要GNS的帮助指出当前ISMG该如何传递短信。

其中,后二方面属于移动短信息系统内部实现,对于SP来讲大概可以“透明”来看待,只要实现了SP同ISMG的正确交互,就可以实现接入移动梦网短信系统。我们关心的只是SP端的开发细节。

二、CMPP交互模式

从手机用户角度讲,按短信的发起/接收路径来讲,有两个叫法:

MT(Short Message Mobile Terminated, SMMT),短信接收,短信从SP发送到手机用户。

MO (Short Message Mobile Originate,SMMO),短信发送,短信从手机用户端发送到目标SP。

这两类短信交互,从SP端来看,都是属于Socket传输应用,CMPP的协议是以TCP/IP协议作为底层承载协议的,属于TCP/IP协议栈之上的应用。

SP同ISMG的交互连接分长连接短连接

所谓短连接,就是一次连接,传输一个消息,然后等待回复后拆除连接,显然,效率很低,所以,基本上不被考虑(实际应用移动也不允许SP采用短连接,只是不明白移动为什么还要写入文档? ISMG间会需要?)

所谓长连接,就是SP建立同ISMG连接,然后不断将数据包(一个个CMPP消息)发送到ISMG,此处发送不必等待某条消息的ISMG回应消息返回,就接着发送下一个消息。同时,等待ISMG返回信息或者等待ISMG发送给SP的消息。发送同接收消息不是一定要同步的,实际采用异步(同时也时双工)模式。从效率上,显然,必须全双工的异步模式才能够满足实际应用需求。

如下图(摘自CMPP2.0官方文档)所示,演示了长连接模式数据传输过程:


三、SP端开发

1. 消息分类

首先,图中的CMPP消息有很多种,SP同ISMG之间交流这些消息。大体上这些消息发出后,对方往往需要回复一个应答(RESP)类消息。注意,这些消息大多具有方向性,也就是说只能够从一端到另一端,而不可反方向进行,有些(少数)则可两端都能够发出。以下信息主要来源于移动的文档,但针对大家易混淆或源文档解释不够详细做了明确和补充。具体见下表:

消息名

传递方向

解释说明

CMPP­_CONNECT

SP---àISMG

CMPP_CONNECT操作的目的是SP向ISMG注册作为一个合法SP身份,此消息需要向ISMG发出验证信息,验证方式采用md5加密密码方式,若注册成功后即建立了应用层的连接(否则ISMG会立即断开Socket),此后SP可以通过此ISMG接收和发送短信。

ISMG以CMPP_CONNECT_RESP消息响应SP的请求。具体的算法实现参考CMPP2.0文档和本文附件代码。

CMPP_CONNECT_RESP

SPß---ISMG

ISMG对CMPP_CONNECT消息的回复(无论是否验证成功);如果未通过,会在消息中包含参考信息,但ISMG会立即断开连接。

CMPP­_ACTIVE_TEST

SPßàISMG

这个消息通信双方都可以发出,目的是在没有其他消息发送时,保持双方的通信链路的连接,避免系统认为通信通道已经关闭。每一个收到此消息的实体应当返回CMPP_ACTIVE_TEST_RESP消息,以“礼节性”表示自己的还在通信,维持数据连接有效性。

不过,据网友交流,有些厂家实现的ISMG,仅仅靠自己发出此消息等待SP回答CMPP_ACTIVE_TEST_RESP来确定数据链路的有效性,而忽略SP的CMPP_ACTIVE_TEST消息(有些霸道吧?)这个值得注意,不要仅仅实现发送而不响应此消息,避免数据连接失效。

CMPP_ACTIVE_TEST_RESP

SPßàISMG

对通信的另一端的CMPP_ACTIVE_TEST消息的回复。作用参考CMPP_ACTIVE_TEST的解释。

CMPP­_SUBMIT

SP---àISMG

在正确建立了数据连接后,SP向ISMG发送一个SMS数据包。本消息需要仔细研究。接收到此消息后,ISMG需要以CMPP_SUBMIT_RESP消息作为回答。如果在一定时间时间内(移动给出的参考值60秒)内未得到消息回应,那么SP需要重新发送此数据包,以确保消息得到投递。如果重发达到3次后仍然得不到回应,SP端应该考虑可能ISMG已经失效,应当停止发送此短消息。

CMPP­_SUBMIT_RESP

SPß---ISMG

该消息由ISMG发送给SP,同时返回一个“收条”(源CMPP_SUBMIT消息的ISMG端的标示MSGID)给SP,表示“我ISMG已经确认收到你这条消息了”。收到此消息后,SP需要保留此“收条”,因为后面ISMG会最终报告本消息是否正确发送到用户手机。那个报告就是以此消息的“收条”作为确认那一条消息的。

CMPP_QUERY

SP---àISMG

这个查询不是查询单条消息的,是查询SP发送给ISMG的短信的业务情况。可以查总计数,还可以分类查询。(基本就是发起对移动sms业务数据库的查询统计)

CMPP_QUERY_RESP

SPß---ISMG

ISMG将查询的数据返回给SP。

CMPP_CANCEL

SP---àISMG

SP发起的取消某条消息的命令消息,其中包含了之前已经发送给ISMG消息的“收条”以便ISMG可以确定是那一条消息。如果消息已经发送给用户了,那么此消息/命令会无效,ISMG返回失败。

CMPP_CANCEL_RES

SPß---ISMG

ISMG返回的对CMPP_CANCEL的回复,并告知是否删除成功。

CMPP_DELIVER

SPß---ISMG

当有MO或者状态报告时,ISMG发送此消息。注意,此消息的数据可以是用户手机发送给SP的消息,也可是对于之前SP发送到ISMG的短信的最终状态的回复,报告短信的最终状态。

CMPP_DELIVER_RESP

SP---àISMG

SP礼节性的回复告知收到CMPP_DELIVER消息。要指出SP报告的CMPP_DELIVER消息的MSGID,以便ISMG知道那一条消息SP已经确认收到。

CMPP_TERMINAT

SPßàISMG

SP和ISMG都可以主动发消息给对方,自己这端由于某种原因需要终止当前的数据连接。终止后,要经过重新Connection(验证)之后才可以(进入事务阶段)发送SMS数据消息。

CMPP­_TERMINATE_RES

SPßàISMG

通知对方,本端已经最好撤除连接的准备。

 

2. 交互阶段

整个CMPP协议交互分为验证事务两个阶段。验证阶段,发送CMPP_CONNECTION消息进行验证,通过验证后(必须要通过才)进入CMPP事务阶段,可以发送短信数据了。上表中的CMPP_CONNECTION以下的消息都属于事务阶段的消息。

3. 消息数据结构

每一个消息包含 消息头消息体两个部分,头固定长度为12字节,其他消息长度各异,但是同一类型消息的长度是固定的。所有消息的各个字段基本上仅有3种类型:Unsigned Integer (无符号整型) 、Integer(整型)、Octet String(字符串),每种类型具体长度不定,网络字节顺序。

1、 消息头(3个Unsigned Integer字段组成):

4字节的Total_Length (Unsigned Integer),包含了此消息的总计(包括了头部分)长度。

4字节的Command_Id(Unsigned Integer),指明了此消息到底是什么消息,就是上表中消息的枚举值。应用程序根据此值确定本数据包到底是什么消息,从而可以按照确定的消息类型,解析余下的消息体。

4字节的Sequence_Id(Unsigned Integer),指明了此数据包在发送此消息端的唯一编号。这个唯一编号,实际上可以看作流水操作编号。因为分析到交互模式我们看到,SP发送数据到ISMG,不是每发送一个就停下来等待ISMG的回复,而是“一下子”发送多个数据包过去,然后等待ISMG的回应。然而,怎么知道回应的消息是到底对应之前发送过去的消息中的那一条呢?本字段就是解决此难题。SP按照编号发送消息过去,等待ISMG的回应—一般情形下回应消息数据结构都有表明本消息回应的是SP发出的哪一条消息,这个对应就是依靠Sequence_Id。它并不要求一定要严格唯一,但是在给定的一段时间内,必须唯一(基本上只要SP发送过去的消息中没有重复就行了)。如果是需要SP回答的消息,SP也必须将ISMG发送过来的消息的Sequence_Id填入相应字段,表明这是某个消息的回应。SP端和ISMG端Sequence_ID都没有确定具体的算法。SP可以(但不推荐)采用数据库的唯一Id作为此值。

2、消息体。消息体长度根据消息不同,长度不一。其他的参考移动的文档《中国移动通信互联网短信网关接口协议(China Mobile Peer to Peer, CMPP)(V2.0)》,这里着重讲讲2个重要消息的消息体数据结构:

CMPP­_SUBMIT的消息体:

字段名

长度(byte)

类型

描述

Msg_Id

8

Unsigned Integer

信息标识,应该由SP侧ISMG本身产生,本处填空,供ISMG传输时使用。SP提交时候应当留空。

Pk_total

1

Unsigned Integer

相同Msg_Id的信息总条数,从1开始。如果一条消息长度超多一条短信,可能需要分解成多条消息,那么实际上这多条消息属于一条完整消息,所以可以根据此给分解得到的多条短信进行编号,那么总计需要编成多少条短信,此处就填写多少。

Pk_number

1

Unsigned Integer

相同Msg_Id的信息序号,从1开始。编号决定消息的相对位置。

Registered_Delivery

1

Unsigned Integer

是否要求返回状态确认报告:

0:不需要

1:需要

2:产生SMC话单(该类型短信仅供网关计费使用,不发送给目的终端)。

一般情况下,都需要确认报告。SMC话单也需要返回是否成功的报告。这条消息用于包月SMC时,当你发送消息给移动的ISMG,移动的计费系统会一次性扣除用户的信息费,但是此消息不会送到用户手机。但是注意,有的ISMG厂商(很可能是移动要求)实现此消息时候,如果你并没有发送任何此包月类型的消息给用户手机,是不发生扣费行为的。移动会认为这是属于违规的“代收费”行为,会影响同移动的合作关系。

Msg_level

1

Unsigned Integer

信息级别,信息的优先级。不过实际当中,感觉ISMG端并没有区分优先级。

Service_Id

10

Octet String

业务类型,是数字、字母和符号的组合。这个表示业务的字符串可以给发出的短信分类。通过此字段大约可以知道每个服务项目的业务量,有利于统计和计费以及结算。

Fee_UserType

1

Unsigned Integer

计费用户类型字段

0:对目的终端MSISDN计费;

1:对源终端MSISDN计费;

2:对SP计费;

3:表示本字段无效,对谁计费参见Fee_terminal_Id字段。

Fee_terminal_Id

21

Unsigned Integer

被计费用户的号码(如本字节填空,则表示本字段无效,对谁计费参见Fee_UserType字段,本字段与Fee_UserType字段取0、1、2时互斥)

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_Content字段的字节内容应该按照什么编码来解码/编码。

Msg_src

6

Octet String

信息内容来源(SP的企业代码),例如919000。

FeeType

2

Octet String

资费类别

01:对“计费用户号码”免费

02:对“计费用户号码”按条计信息费

03:对“计费用户号码”按包月收信息费

04:对“计费用户号码”的信息费封顶

05:对“计费用户号码”的收费是由SP实现。

通常值为02,注意这是一个字符串,并非整型。

FeeCode

6

Octet String

资费代码(以分为单位),如:“0050”代表人民币0.50元。

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个用户),通常是1。移动是忌讳一条消息发给多个用户的。

Dest_terminal_Id

21*DestUsr_tl

Octet String

接收短信的MSISDN号码,一个类似字符串数组的结构。受DestUsr_tl的约束,决定了本字段的长度。

Msg_Length

1

Unsigned Integer

信息长度(Msg_Fmt值为0时:<160个字节;其它<=140个字节)。如果是ASCII码,可以达到160个英文字母。原因是因为英文字母仅占用7bit,而中文等双字节代码需要16位,同时每一个字节最高为都占用,所以最多140个字节,也就是70个汉字。

Msg_Content

Msg_length

Octet String

信息内容

Reserve

8

Octet String

保留

CMPP_SUBMIT消息长度是可变的,将SP端的消息发送给ISMG,ISMG将返回一个MSGID给SP标示此消息,之后(48小时以内,但一般最多几分钟内就可),ISMG返回关于此消息的递送报告。递送报告同MO短消息是通过另外一个重要消息CMPP­_DELIVER来提交给SP的:

CMPP­_DELIVER的各个字段:

字段名

字节数

属性

描述

Msg_Id

8

Unsigned Integer

信息标识

生成算法如下:

采用64位(8字节)的整数:

(1)时间(格式为MMDDHHMMSS,即月日时分秒):bit64~bit39,其中

bit64~bit61:月份的二进制表示;

bit60~bit56:日的二进制表示;

bit55~bit51:小时的二进制表示;

bit50~bit45:分的二进制表示;

bit44~bit39:秒的二进制表示;

(2)短信网关代码:bit38~bit17,把短信网关的代码转换为整数填写到该字段中。

(3)序列号:bit16~bit1,顺序增加,步长为1,循环使用。

各部分如不能填满,左补零,右对齐。

Dest_Id

21

Octet String

目的号码

SP的服务代码,一般4--6位,或者是前缀为服务代码的长号码;该号码是手机用户短消息的被叫号码。

Service_Id

10

Octet String

业务类型,是数字、字母和符号的组合。

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汉字

Src_terminal_Id

21

Octet String

源终端MSISDN号码(状态报告时填为CMPP_SUBMIT消息的目的终端号码)

Registered_Delivery

1

Unsigned Integer

是否为状态报告

0:非状态报告(MO SMS)

1:状态报告

此字段决定了CMPP­_DELIVER消息到底是手机上行一条消息到SP还是ISMG向SP报告之前发送的消息最终递送状态。

Msg_Length

1

Unsigned Integer

消息长度。是指Msg_Content字段的长度。

Msg_Content

Msg_length

Octet String

消息内容。如果消息不是状态报告,那么按照Msg_Fmt指示解码为特定编码的字符串内容。

Reserved

8

Octet String

保留项

如果是报告,那么Msg_Content将按照状态报告结构来解释:

字段名

字节数

属性

描述

Msg_Id

8

Unsigned Integer

信息标识

SP提交短信(CMPP_SUBMIT)操作时,与SP相连的ISMG产生的Msg_Id。

这个MSGID实际上就是SP之前发送一个CMPP_SUBMIT消息之后的CMPP_SUBMIT_RESP消息中返回的关于CMPP_SUBMIT消息的ISMG编号.,根据此MSGID可以知道那条消息最终确定的递送状态。

Stat

7

Octet String

发送短信的应答结果,含义与SMPP协议要求中stat字段定义相同,详见下面。SP根据该字段确定被报告的CMPP_SUBMIT消息的处理状态。

Submit_time

10

Octet String

YYMMDDHHMM(YY为年的后两位00-99,MM:01-12,DD:01-31,HH:00-23,MM:00-59)

Done_time

10

Octet String

YYMMDDHHMM

Dest_terminal_Id

21

Octet String

目的终端MSISDN号码(SP发送CMPP_SUBMIT消息的目标终端)

SMSC_sequence

4

Unsigned Integer

取自SMSC发送状态报告的消息体中的消息标识。

关于State字段,如下解释:

消息状态名

最终状态

描述

DELIVERED

DELIVRD

消息到达目标

EXPIRED

EXPIRED

消息过期

DELETED

DELETED

消息被删除

UNDELIVERABLE

UNDELIV

消息未被送达

ACCEPTED

ACCEPTD

消息被认可

UNKNOWN

UNKNOWN

未知状态

REJECTED

REJECTD

消息被弹回

其他消息结构,具体说明见中移动的CMPP协议。

4. 安全验证

CMPP协议在CMPP_CONNECT中传递验证消息。验证消息为9字节的0 移动给出的密码 当前时间戳字节数组的MD5算法后的字节。时间戳为 月日时分秒,10位。代码算法如下:

private byte[] getMd5Code()

{

byte[] buf=new byte[6 9 _Password.Length 10] ;

byte[] s_a=Encoding.ASCII.Get

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CMPP模拟器主要是模拟使用中国移动CMPP协议(版本1.x~3.x)的各种网关。此类型网关只使用一个收发连接(短信接收和发送在一个链接上进行)。 模拟器要求使用JDK1.4以上的Java运行环境,请确认相关环境已经安装妥当。如果还没有安装Java环境,请访问java.sun.com下载最新J2SE的SDK。 此模拟器已经使用了全新的核心设计,主要针对应用程序的稳定性、可靠性、效率以及配置、管理和监控方面做了很大的调整。基本界面风格和应用功能上没什么变化。 1.建立Socket连接与登陆 使用自己的CMPP客户端程序,与7890端口建立Socket连接。然后按照CMPP协议发送登陆数据包。模拟器会按照协议处理相关连接和登陆过程。 2.发送短信息 正确建立连接和登陆以后,可以按照CMPP协议的Submit过程提交相关数据并得到应答。模拟器在接收到数据以后,会进行解析并按照协议要求进行应答和回复。相关的处理信息会记录在日志文件中。 3.接收短信息 正确建立连接和登陆以后,在同一连接上等待模拟器的Deliver数据包即可,并且要求客户端按照协议给予应答。模拟器会对相关过程记录在日志信息当中。 4.模拟MT以及状态报告过程 发送submit时,请将registered_delivery设置为1即可。 模拟器收到相关数据包以后,会通过submit_response应答给出message_id;随后模拟出deliver数据包给出状态报告,其中registered_delivery为1。 5.模拟MO过程 发送submit时,请将registered_delivery设置为0即可。 模拟器收到相关数据包以后,会通过deliver请求发送模拟的MO。其中deliver的相关数据全部来自接收到的submit数据。包括来源号码、目标号码、业务代码以及信息内容。 6.模拟压力测试 如果需要进行模拟的完整压力测试过程,只需要以最大速度重复步骤5即可。 模拟器的监控 模拟器有一个基于Web监控后台,系统启动的时候同时启动。缺省端口建立在8081上。监控的URL地址、用户名和密码可以在配置文件中找到。 http://localhost:8081 forest_luo root

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值