惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

MyScale Blog
MyScale Blog
P
Privacy International News Feed
Hugging Face - Blog
Hugging Face - Blog
U
Unit 42
博客园 - 叶小钗
月光博客
月光博客
Microsoft Security Blog
Microsoft Security Blog
Apple Machine Learning Research
Apple Machine Learning Research
The Cloudflare Blog
Project Zero
Project Zero
Cisco Talos Blog
Cisco Talos Blog
The Hacker News
The Hacker News
T
Tor Project blog
阮一峰的网络日志
阮一峰的网络日志
Google DeepMind News
Google DeepMind News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Help Net Security
Help Net Security
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Security Latest
Security Latest
I
Intezer
L
LINUX DO - 最新话题
Blog — PlanetScale
Blog — PlanetScale
T
The Exploit Database - CXSecurity.com
Hacker News - Newest:
Hacker News - Newest: "LLM"
酷 壳 – CoolShell
酷 壳 – CoolShell
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Webroot Blog
Webroot Blog
WordPress大学
WordPress大学
A
About on SuperTechFans
P
Proofpoint News Feed
T
Tailwind CSS Blog
I
InfoQ
The Register - Security
The Register - Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
AWS News Blog
AWS News Blog
博客园 - Franky
Simon Willison's Weblog
Simon Willison's Weblog
Last Week in AI
Last Week in AI
博客园 - 聂微东
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Google Online Security Blog
Google Online Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Attack and Defense Labs
Attack and Defense Labs
T
Tenable Blog
大猫的无限游戏
大猫的无限游戏
K
Kaspersky official blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
W
WeLiveSecurity
S
Security @ Cisco Blogs
MongoDB | Blog
MongoDB | Blog

博客园 - 清风徐来,水波不兴

健康同步专家 隐私政策 健康同步专家介绍 IOS动画实现(3)UIView封装的动画 IOS动画实现(2)ImageView自带动画 IOS动画实现(1)几种实现方式 学习CEGUI亟待解决问题二:消息事件传递机制问题 学习CEGUI亟待解决问题一:文本控件的格式问题 第一讲 ERP初阶(四):MRP基本构成 ERP初阶(三):MRP基本原理 ERP初阶(二):ERP概念与历程 ERP初阶(一):走近ERP 协议开发 中移动CMPP2.0协议API(四) 协议开发 中移动CMPP2.0协议API(三) 协议开发 中移动CMPP2.0协议API(一) 短信网关简介 SP 短信开发-PROVISION接口实现-反向取消实例代码 SP 短信开发-PROVISION接口实现-正向订购实例代码 SP 短信开发-PROVISION接口实现1
协议开发 中移动CMPP2.0协议API(二)
清风徐来,水波不兴 · 2007-01-21 · via 博客园 - 清风徐来,水波不兴

协议开发 中移动CMPP2.0协议API(二)

云网(jimzj@21cn.om)

接上篇:

其实说到API的开发,也只是包装了一个通讯协议。让上层用户可以不用去知道详细的协议解释,而专注于自己的业务模块。

对于CMPP2.0协议,要用的指令也就8个,相对来说并不是很复杂

CMPP_CONNECT          =0x00000001; //       请求连接

CMPP_CONNECT_RESP     =0x80000001; //       请求连接应答

CMPP_TERMINATE        =0x00000002; //       终止连接

CMPP_TERMINATE_RESP   =0x80000002; //       终止连接应答

CMPP_SUBMIT           =0x00000004; //       提交短信

CMPP_SUBMIT_RESP      =0x80000004; //       提交短信应答

CMPP_DELIVER          =0x00000005; //       短信下发

CMPP_DELIVER_RESP     =0x80000005; //       下发短信应答

CMPP_QUERY            =0x00000006; //       短信状态查询

CMPP_QUERY_RESP       =0x80000006; //       短信状态查询应答

CMPP_CANCEL           =0x00000007; //       删除短信

CMPP_CANCEL_RESP      =0x80000007; //       删除短信应答

CMPP_ACTIVE_TEST      =0x00000008; //       激活测试

CMPP_ACTIVE_TEST_RESP =0x80000008;       //     激活测试应答

实现CMPP协议模块也就是实现上面的8个指令就可以了。按照上面说的设计模式,同进结合API开发来说一下协议的实现。

对于API对外的接口,一般的定义格式如下:

extern "C" __declspec( dllexport ) int WINAPI ActiveTest()

接下来就是实现接口的功能:

一、建立SOCKET连接

struct sockaddr_in _socaddr ;

    _socaddr.sin_family      = AF_INET;

    _socaddr.sin_port        = htons( _port );

    _socaddr.sin_addr.s_addr = inet_addr( _ismg );

        return connect( _soc, (struct sockaddr *)&_socaddr, sizeof( _socaddr ));

致于设置发送超时,接收超时还有阻塞或非阻塞的接收模式,可以自己根据需要去设置不同的目标值。

、登录短信网关服务器

CMPP协议,主要的部分是就是AuthenticatorSource = MD5Source_Addr+9 字节的0 +shared secret+timestamp),MD5算法在网上可以直接找到源程序,不必要自己重新去写这个内容。这部分内容相对比较简单就不在这里再写出来了。

//计算单向HASH函数的值

    strcpy( authsrc, _spid ) ;

       char * pos = authsrc + strlen( _spid ) + 9 ;  //9 字节的0

    strcpy( pos, _passwd ) ;

       pos += strlen( _passwd );

       strcpy( pos, _timestamp( timestr ));    //时间戳

       pos += strlen( timestr );

    ctx.update(( unsigned char * )authsrc, (int)( pos - authsrc ));

       ctx.finalize();

    ctx.raw_digest( msg->digest );              //复制转换成MD5的字符串到发送数据中

三、提交短信息

相对于登录来说,提交短信也不会很复杂。只是简单的把客户端程序提交过来的数据复制到发送窗口,发送并等待网关回应的状态就可以了,当然也可以在接收到用户的数据前作一些适当的如:手机号码是否全数字,定时发送或存活时间是否正确等的判断。

//要注意的就是可变的用户数据与保留字段的内容:

memcpy( _pkg->data, &msg, sizeof( CMPP_SUBMIT ));

               //将最后8个字节的保留数据拷贝到适当的位置

              memcpy(

               ( _pkg->data + nsize - sizeof( msg.reserve ) - sizeof( CMPP_HEAD )),

               msg.reserve,

               sizeof( msg.reserve ));

四、接收短信息和状态

        接收短信后有两种处理方式,

1、  采用回调函数的方式:

这种方式相对于API来说比较简单,只要定义一下接口函数就可以了,客户端程序在初始化时,传入回调函数的函数指针,当API接收到短信网关下发(DELIVER)的短信时,调用函数指针把相关参数据传递给客户端。不必要考虑队列或其它细节的问题。

如下我在API中定义的回调函数:

typedef int ( WINAPI * TProcGetDeliver )(

            char * msgid,

            unsigned char * destnumber,

            unsigned char * serviceid,

            unsigned char tppid,

            unsigned char tpudhi,

            unsigned char msgfmt,

            unsigned char * srcnumber,

            unsigned char delivery,

            unsigned char msglen,

            unsigned char * msgcontent,

            unsigned char * reserve,

            unsigned char * stat,

            unsigned char * submittime,

unsigned char * donetime ) ;

              而在API对外接口中只要定义一个参数作为传送函数指针就可以了:如下:

              extern "C" __declspec( dllexport ) int WINAPI IFInitInterface( char *ismg, unsigned short port, TProcGetDeliver fCltGetDeliver );

              fCltGetDeliver 就是用户传递过来的回调函数指针,在调用时,直接采用参数开式用调用就可以了。如下所示:

              err = _fCltGetDeliver ( (char * )&_msgid,

                                _msg->destnumber,

                                _msg->serviceid,

                                _msg->tppid,

                                _msg->tpudhi,

                                _msg->msgfmt,

                                _msg->srcnumber,

                                _msg->delivery,

                                _msg->msglen,

                                _msg->msgcontent,

                                _msg->reserve,

                                _stat,

                                _submittime,

                                _donetime

                                 ) ;

              这样所接收到的所有参数就顺利传递到客户端了。

2、  调用API的客户端程序定时检测并从缓冲队列中拾取方式:

对于队列的方式,API内部必需自己建立一个缓冲队列。这个队列对于安全来说,必须是线程安全的(可以用临界区来保护),接收到一个下发信息时,数据暂时保存入队列中:

       int nl = sizeof( CMPP_HEAD ) + sizeof( CMPP_DELIVER ) ;

        _pushrecqueue( _recpkg, nl ) ;

下面是_pushrecqueue函数;

void WINAPI _pushrecqueue( void * inval, int nl )

{

    char * _queval = new char[ nl + 1 ] ;

    memset( _queval, 0, sizeof( nl + 1 )) ;

    memcpy( _queval, inval, nl ) ;

    _queue._push( _queval ) ;

}

为了保证数据最大安全性,不要接收到过多的数据进入队列。放入队列的数据就等待用户用API接口过来取走就可以了,其相关接口与回调函的参数相差不多,在这里就不多作说明,只要说明一下可以提供一个接口,可以让客户端可以检测队列中是否有可以接收的数据:

       extern "C" __declspec( dllexport ) int WINAPI HasDeliver() ;

        这检是否取数据就由客户端去作判断了。待续......