ActiveSync应用层程序协议分析-RAPI的握手过程
来源:互联网 发布:me域名邮箱 编辑:程序博客网 时间:2024/06/05 16:04
ActiveSync应用层程序协议分析-RAPI的握手过程
转载时请注明出处和作者联系方式
作者联系方式:李先静 <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;
}
~~end~~
- ActiveSync应用层程序协议分析-RAPI的握手过程
- ActiveSync应用层程序协议分析-RAPI的握手过程
- ActiveSync应用层程序协议分析-RAPI的握手过程 - 李先静的专栏 - CSDNBlog
- 如何在应用层控制TCP三次握手的过程
- SSL协议的握手过程
- SSL协议的握手过程
- SSL协议的握手过程
- SSL协议的握手过程
- SSL协议的握手过程
- Tcpdump分析TCP协议三次握手过程
- TCP协议三次握手过程分析【转】
- TCP协议三次握手过程分析
- 【转】TCP协议三次握手过程分析
- TCP协议三次握手过程分析
- TCP协议三次握手过程分析
- TCP协议三次握手过程分析
- TCP协议三次握手过程分析
- TCP协议三次握手过程分析
- Java NIO类库Selector机制解析(上)
- 什么叫GPS、GPS的原理
- 于丹《庄子》心得讲稿-《心态与状态》
- 软件过程模型的分类与选用
- 向UltraWebGrid中绑定WebDateChooser
- ActiveSync应用层程序协议分析-RAPI的握手过程
- GLONASS系统介绍
- Java NIO类库Selector机制解析(下)
- MANOI AT01:如何成为一个世界级的短跑机器人
- extjs的combobox的用法
- WEB将把我们带向何方
- 关于Tomcat5.0和jdk1.4安装的一些心得。
- “VM6辅助启动.bat”生成器.hta
- “伽利略”卫星定位系统(GNSS系统) 什么是“伽利略”计划