ActiveSync应用层程序协议分析-RAPI的握手过程

本文详细介绍了ActiveSync中RAPI协议的握手过程及设备信息结构,包括设备与PC端的交互流程与数据编码方式。
转载时请注明出处和作者联系方式
作者联系方式:李先静 <xianjimli at hotmail dot com>
 
ActiveSync与Window Mobile之间的通信协议并不复杂,在RNDIS+USBNET之上运行TCP/IP,而TCP/IP之上的应用层协议包括RAPI和RRAC两个协议。前段时间我完成RAPI和RRAC协议的PC端和设备端的实现,在这个系列之中,我们将对它们的原理和实现进行分析,供要做类似工作的朋友参考。本文介绍一下RAPI的握手过程。
 
PC端的ActiveSync监听990端口,同步时设备连接到这个端口,然后开始握手:
 
1.设备端发送四个字节的数据(0x00)表示请求握手。
2.PC端回应四个字节的数据(0x03)表示接受握手,并要求设备提供设备信息。
3.设备回应四个字节的数据(0x04)表示要上传设备信息,并在其后紧跟设备信息。
4.PC端读取设备信息,如果不要求论证,握手到此结束(要求握手的情况目前还不清楚)。
 
设备信息结构如下:
 
       typedef struct _RapiDeviceInfo
       {
              RapiDeviceGuid   guid;
              unsigned int os_version_major;
              unsigned int os_version_minor;
              WStr* name;
              unsigned int dev_version;
              unsigned int cpu_type;
              unsigned int dev_magic;
              unsigned int current_partner;
              unsigned int dev_id;
              char* platform;
              char* model;
              unsigned int components_nr;
              RapiComponent* components;
              unsigned int pw_key;
       }RapiDeviceInfo;
 
这个数据包前面四个字节是这个结构的数据长度,后面的数据并不是直接按结构内存布局映射过来的,而是有专门编码方式。主要特殊之外在于,所有整数都是以小端格式存放,name之前有四个字节代表name的字符数(不包括空字符), platform之前有四个字节代表platform的字节数(此时包括空字符),model之前有四个字节代表model的字节数(此时不包括空字数)。由这个结构可以看出微软当时把这个协议定义得太烂了:name是宽字符,而platform和model是多字节字符串,和前面的name不统一不说,还无法知道它们的编码方式,更烂的是platform和model前面长度的意义不一致。
 
PC端的代码类似于:
static AsmRet rapi_host_connection_device_handle_hand_shake(AsmConnection* thiz)
{
       AsmRet ret = ASM_RET_FAIL;
       asm_return_val_if_fail(thiz != NULL, ASM_RET_FAIL);
       PrivInfo* priv = (PrivInfo*)thiz->priv;
       asm_return_val_if_fail(priv->stream != NULL, ASM_RET_OK);
 
       int length = 0;
       unsigned int cmd = 0;
       unsigned int resp = 0;
       AsmInputBuffer* input = NULL;
       do
       {
              ret = asm_stream_read(priv->stream, &cmd, sizeof(cmd), &length);
              if(ret != ASM_RET_OK || cmd != RAPI_COMMAND_HAND_SHAKE) break;
 
              resp = RAPI_RESP_HAND_SHAKE;
              ret = asm_stream_write(priv->stream, &resp, sizeof(resp), &length);
              if(ret != ASM_RET_OK) break;
      
              ret = asm_stream_read(priv->stream, &cmd, sizeof(cmd), &length);
              if(ret != ASM_RET_OK || cmd != RAPI_RESP_GET_INFO) break;
             
              input = asm_input_buffer_create(NULL, 0, ASM_ENDIAN_LITTLE, NULL);
              ret = rapi_stream_read(priv->stream, input);
              if(ret != ASM_RET_OK) break;
              ret = rapi_host_connection_device_parse_device_info(thiz, input);
       }while(0);
      
       if(ret != ASM_RET_OK)
       {
              asm_stream_destroy(priv->stream);
              priv->stream = NULL;
              printf("%s:%d hand shake failed./n", __func__, __LINE__);
       }
       asm_input_buffer_destroy(input);
 
       return ASM_RET_OK;
}
 
设备端的代码类似于:
static AsmRet rapi_device_connection_device_hand_shake(AsmConnection* thiz)
{
       AsmRet ret = ASM_RET_FAIL;
       asm_return_val_if_fail(thiz != NULL, ret);
 
       PrivInfo* priv = (PrivInfo*)thiz->priv;
       RapiDeviceInfo info = {0};
       size_t length = 0;
       unsigned int cmd = 0;
       unsigned int resp = 0;
 
       asm_output_buffer_reset(priv->output);
       cmd = uint32_to_endian(RAPI_COMMAND_HAND_SHAKE, ASM_ENDIAN_LITTLE);
 
       ret = asm_stream_write(priv->stream, &cmd, sizeof(cmd), &length);
       assert(length == sizeof(cmd));
 
       ret = asm_stream_read(priv->stream, &resp, sizeof(resp), &length);
       assert(length == sizeof(resp));
       assert(resp == RAPI_RESP_HAND_SHAKE);
 
       cmd = uint32_to_endian(RAPI_RESP_GET_INFO, ASM_ENDIAN_LITTLE);
       ret = asm_stream_write(priv->stream, &cmd, sizeof(cmd), &length);
       assert(length == sizeof(cmd));
 
       if(rapi_device_get_info(priv->device, &info) == ASM_RET_OK)
       {
              if(rapi_buffer_write_info(priv->output, &info) == ASM_RET_OK)
              {
                     ret = rapi_stream_write(priv->stream, priv->output);
              }
       }
 
       return ret;
}
 
内容概要:本研究聚焦于绿电直连型电氢氨园区的优化运行,提出一种集成绿色电力直接供给、电解水制氢及氢气合成氨工艺的综合能源系统架构。通过建立包含风光发电、电解槽、氨合成反应器、储氢罐、电网交互及多类型负荷在内的系统模型,综合考虑绿电直供优先、能量梯级利用与多能互补原则,构建以系统综合运行成本最小化为目标的优化调度模型。研究采用Matlab与Python工具进行算法求解和仿真分析,利用实际气象与负荷数据完成案例验证,评估了不同运行策略下系统的经济性、可再生能源消纳能力与碳减排效益,为新型电氢氨一体化园区的规划与运行提供了理论依据和技术支撑。; 适合人群:具备一定电力系统、新能源或化工背景的研究生、科研人员及从事综合能源系统规划与优化工作的工程技术人员。; 使用场景及目标:①用于科研学习,理解电--氨多能转换系统的建模与优化方法;②为工业园区的低碳化、智能化改造提供技术参考与决策支持;③作为开发类似综合能源管理系统的理论基础。; 阅读建议:此资源包含完整的模型代码、数据与论文,使用者应结合代码仔细研读论文中的模型构建部分,重点关注目标函数与约束条件的设计逻辑,并尝试修改参数进行仿真,以深入掌握优化算法在实际系统中的应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值