一天写了个Carlife 协议数据分流器

 #include <stdio.h>
#include <string.h> typedef unsigned char uint8_t;
typedef unsigned int uint32_t; void print_array_data(uint8_t* data, size_t len)
{
int i;
char log_buffer[];
strcpy(log_buffer," ");
for(i=;i<len;i++)
{
char num_buffer[];
sprintf(num_buffer,"%02x ",data[i]);
strncat(log_buffer,num_buffer,);
if(strlen(log_buffer) > ) break;
}
printf("%s\n",log_buffer);
} class MsgReceiver
{
public:
void processData(uint8_t channel, uint8_t* buf, size_t size)
{
printf("channel %d, data is ", channel);
print_array_data(buf,size);
}
}; class MsgDispatch
{
public:
MsgDispatch(){
itsBufferData = new uint8_t[*];
itsCachedBufferSize = ;
itsMode = eParseHeader;
itsChannel = ;
itsCachedHeaderSize = ;
itsHeaderData = new uint8_t[MSG_HEADER_SIZE];
itsMsgRecv = new MsgReceiver;
}
~MsgDispatch(){
delete [] itsBufferData;
delete [] itsHeaderData;
delete itsMsgRecv;
}
void dispatch(uint8_t* buf, size_t size)
{
uint32_t curProcessIndex = ;
//printf("dispatch mode = %d, buffer size %lu, buffer data is ",itsMode,size);
//print_array_data(buf,size);
if(itsMode == eParseHeader)
{
if(size >= MSG_HEADER_SIZE) /* we can process header size */
{
if(isValidHeader(buf))
{
uint8_t channel = buf[];
uint32_t dataLen = readBig32(buf + ); curProcessIndex += MSG_HEADER_SIZE;
if (curProcessIndex + dataLen <= size)
{
itsMsgRecv -> processData(channel, buf + curProcessIndex, dataLen);
curProcessIndex += dataLen;
}
else /* we need to cache data */
{
cacheData(buf + curProcessIndex, size - curProcessIndex, dataLen, channel);
itsMode = eReadData;
curProcessIndex = size;
}
}
else /* header is not correct, shift one byte */
{
curProcessIndex++;
}
}
else /* process data is less than header size, cache header */
{
memcpy(itsHeaderData,buf,size);
itsCachedHeaderSize = size;
curProcessIndex = size;
itsMode = eReadHeader;
}
}
else if (itsMode == eReadData) /* read data */
{
if(size >= itsNeedReadSize) /* we can read all data from current buf */
{
memcpy(itsBufferData + itsCachedBufferSize, buf, itsNeedReadSize);
itsCachedBufferSize += itsNeedReadSize;
itsMsgRecv -> processData(itsChannel, itsBufferData, itsCachedBufferSize);
itsMode = eParseHeader;
curProcessIndex = itsNeedReadSize;
}
else /* can't read all data from current buffer, put all data to cache buffer */
{
memcpy(itsBufferData + itsCachedBufferSize, buf, size);
itsCachedBufferSize += size;
itsNeedReadSize -= size;
curProcessIndex = size;
}
}
else /* read header */
{
uint8_t needReadHeaderSize = MSG_HEADER_SIZE - itsCachedHeaderSize;
if(needReadHeaderSize < size) /* we can read header from current buffer */
{
memcpy(itsHeaderData+itsCachedHeaderSize,buf,needReadHeaderSize);
if(isValidHeader(itsHeaderData))
{
uint8_t channel = itsHeaderData[];
uint32_t dataLen = readBig32(itsHeaderData+); curProcessIndex = needReadHeaderSize;
if (curProcessIndex + dataLen <= size) /* we read data from current buffer */
{ itsMsgRecv -> processData(channel, buf + curProcessIndex, dataLen);
itsMode = eParseHeader;
curProcessIndex += dataLen;
}
else /* we need to cache data */
{
cacheData(buf + curProcessIndex, size - curProcessIndex, dataLen, channel);
curProcessIndex = size;
itsMode = eReadData;
}
}
else /* error header, shift one byte */
{
memcpy(itsHeaderData,itsHeaderData + ,MSG_HEADER_SIZE - );
itsCachedHeaderSize = MSG_HEADER_SIZE - ;
curProcessIndex = needReadHeaderSize;
}
}
else /* can't fill a header size */
{
memcpy(itsHeaderData+itsCachedHeaderSize,buf,size);
itsCachedHeaderSize += size;
curProcessIndex = size;
}
}
if(curProcessIndex < size)
{
this->dispatch(buf+curProcessIndex,size-curProcessIndex);
}
else { } /* data process Done */
}
private:
uint32_t readBig32(uint8_t* ptr)
{
return ( (uint32_t)( \
( ( (uint32_t)( (uint8_t *)(ptr))[ ] ) << ) | \
( ( (uint32_t)( (uint8_t *)(ptr))[ ] ) << ) | \
( ( (uint32_t)( (uint8_t *)(ptr))[ ] ) << ) | \
( (uint32_t)( (uint8_t *)(ptr))[ ] ) ) );
} bool isValidHeader(uint8_t* buf)
{
return (buf[] == 0x00 && buf[] == 0x00 && buf[] == 0x00 && buf[] < 0x07);
} void cacheData(uint8_t* buf, size_t cachedSize, size_t totalDataLen, uint8_t channel)
{
memcpy(itsBufferData,buf,cachedSize);
itsCachedBufferSize = cachedSize;
itsNeedReadSize = totalDataLen - itsCachedBufferSize;
itsChannel = channel;
} enum {
MSG_HEADER_SIZE = ,
};
enum {
eParseHeader,
eReadHeader,
eReadData,
};
uint8_t itsChannel;
uint8_t* itsBufferData;
size_t itsCachedBufferSize;
size_t itsNeedReadSize;
uint8_t itsMode; uint8_t* itsHeaderData;
uint8_t itsCachedHeaderSize;
MsgReceiver* itsMsgRecv;
}; int main()
{
uint8_t muti_msg_buf[] = {0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x04, 0x01,0x02,0x03,0x04, \
0x00,0x00,0x00,0x02, 0x00,0x00,0x00,0x02, 0x02,0x02,\
0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x03, 0x05,0x06,0x07};
uint8_t small_msg_buf_1[] = {0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x05, 0x09,0x08,0x07,0x06};
uint8_t small_msg_buf_2[] = {0x05, 0x00,0x00,0x00,0x02, 0x00,0x00,0x00,0x02, 0x01,0x01};
uint8_t small_msg_buf_3[] = {0x00,0x00,0x00,0x05, 0x00,0x00,0x00,0x0A, 0x01,0x02,0x03};
uint8_t small_msg_buf_4[] = {0x04,0x05,0x06};
uint8_t small_msg_buf_5[] = {0x07,0x08,0x09,0x0A,0x00};
uint8_t small_msg_buf_6[] = {0x00,0x00,0x04, 0x00,0x00,0x00,0x03, 0x07,0x07,0x07, 0x00,0x00,0x00,0x05, 0x00,0x00,0x00,0x03};
uint8_t small_msg_buf_7[] = {0x09,0x09,0x09};
uint8_t error_msg_buf_1[] = {0x01,0x00,0x00,0x00,0x06, 0x00,0x00,0x00,0x01, 0x01,0x02};
uint8_t error_msg_buf_2[] = {0x00,0x00,0x00,0x05, 0x00,0x00,0x00,0x02, 0x02,0x03};
uint8_t error_msg_buf_3[] = {0x00,0x00,0x00,0x04, 0x00,0x00,0x00,0x01, 0x04,0x05,0x05};
uint8_t error_msg_buf_4[] = {0x00,0x00,0x00,0x03, 0x00,0x00,0x00,0x02, 0x05,0x06};
uint8_t error_msg_buf_5[] = {0x00,0x00,0x00,0x02, 0x00,0x00,0x00,0x01, 0x07,0x06,0x05,0x06,0x08,0x00,0x00,0x00};
uint8_t error_msg_buf_6[] = {0x01, 0x00,0x00,0x00,0x03, 0x08,0x09,0x0A, 0x10,0x11};
uint8_t error_msg_buf_7[] = {0x01, 0x04,0x00,0x00,0x00,0x03, 0x00,0x00,0x00,0x04, 0x0B,0x0C,0x0D,0x0E};
uint8_t header_msg_buf_1[] = {0x01,0x00,0x00,0x00,0x06, 0x00,0x00,0x00,0x01, 0x01,0x00};
uint8_t header_msg_buf_2[] = {0x00, 0x00, 0x01, 0x00, 0x00};
uint8_t header_msg_buf_3[] = {0x00, 0x03, 0x01, 0x02, 0x03, 0x01,0x00,0x00,0x00,0x06, 0x00,0x00,0x00,0x01, 0x11}; MsgDispatch mds;
printf("test muti\n");
mds.dispatch(muti_msg_buf,sizeof(muti_msg_buf)); printf("test small\n");
mds.dispatch(small_msg_buf_1,sizeof(small_msg_buf_1));
mds.dispatch(small_msg_buf_2,sizeof(small_msg_buf_2));
mds.dispatch(small_msg_buf_3,sizeof(small_msg_buf_3));
mds.dispatch(small_msg_buf_4,sizeof(small_msg_buf_4));
mds.dispatch(small_msg_buf_5,sizeof(small_msg_buf_5));
mds.dispatch(small_msg_buf_6,sizeof(small_msg_buf_6));
mds.dispatch(small_msg_buf_7,sizeof(small_msg_buf_7)); printf("test error\n");
mds.dispatch(error_msg_buf_1,sizeof(error_msg_buf_1));
mds.dispatch(error_msg_buf_2,sizeof(error_msg_buf_2));
mds.dispatch(error_msg_buf_3,sizeof(error_msg_buf_3));
mds.dispatch(error_msg_buf_4,sizeof(error_msg_buf_4));
mds.dispatch(error_msg_buf_5,sizeof(error_msg_buf_5));
mds.dispatch(error_msg_buf_6,sizeof(error_msg_buf_6));
mds.dispatch(error_msg_buf_7,sizeof(error_msg_buf_7));
printf("test header\n");
mds.dispatch(header_msg_buf_1,sizeof(header_msg_buf_1));
mds.dispatch(header_msg_buf_2,sizeof(header_msg_buf_2));
mds.dispatch(header_msg_buf_3,sizeof(header_msg_buf_3));
return ;
}

输出:

test muti
channel 1, data is 01 02 03 04
channel 2, data is 02 02
channel 1, data is 05 06 07
test small
channel 1, data is 09 08 07 06 05
channel 2, data is 01 01
channel 5, data is 01 02 03 04 05 06 07 08 09 0a
channel 4, data is 07 07 07
channel 5, data is 09 09 09
test error
channel 6, data is 01
channel 5, data is 02 03
channel 4, data is 04
channel 3, data is 05 06
channel 2, data is 07
channel 1, data is 08 09 0a
channel 3, data is 0b 0c 0d 0e
test header
channel 6, data is 01
channel 1, data is 01 02 03
channel 6, data is 11

Msg DisPatch的更多相关文章

  1. 【单页应用之通信机制】view之间应该如何通信

    前言 在单页应用中,view与view之间的通信机制一直是一个重点,因为单页应用的所有操作以及状态管理全部发生在一个页面上 没有很好的组织的话很容易就乱了,就算表面上看起来没有问题,事实上会有各种隐忧 ...

  2. 开源免费跨平台opengl opencv webgl gtk blender, opengl贴图程序

    三维图形的这是opengl的强项,大型3D游戏都会把它作为首选.图像处理,是opencv的锁定的目标,大多都是C的api,也有少部分是C++的,工业图像表现,图像识别,都会考虑opencv的.webg ...

  3. unity 3D + Google Play In-app Billing (IAB)(转) 热度 3

    最近由于工作需要,研究unity如何接入Google Play以实现游戏内购买.目前IAB的实现,prime31做的插件比较好,各平台的IAB均有,但费用相对过高(几乎都是70刀左右,可怜穷小子).在 ...

  4. [译]NeHe教程 - 创建一个OpenGL窗体

    原文: Setting Up An OpenGL Window 欢迎阅读我的OpenGL教程.我是一个热爱OpenGL的普通码农!我第一次听到OpenGL是在3Dfx刚发布他们给Voodoo I显卡的 ...

  5. opengl加载多个3ds模型失败记

    VC6 下载 http://blog.csdn.net/bcbobo21cn/article/details/44200205 opengl环境配置 http://blog.csdn.net/bcbo ...

  6. OPENGL4_变换

    几种变换的几何意义说明 http://blog.csdn.net/onafioo/article/details/22094247 变换的执行顺序问题 正常顺序 1 视图(观察)变换 2 模型变换 3 ...

  7. OPENGL2_基本框架

    一些概念 HDC:设备描述句柄(窗口着色描述表句柄),是WINDOWS的一种数据类型,HDC定义的变量指向一块内存,这块内存用来描述一个设备的相关的内容(设备描述表). HGLRC:OpenGL渲染环 ...

  8. Nehe OpenGL教程第一课-创建一个OpenGL窗口(Win32)

       原文英文地址为:Creating an OpenGL Window (Win32),翻译的chm中文格式文档下载地址为:OpenGL教程电子书(chm格式)中文版,源代码在官网上也可以下载到,每 ...

  9. mosquitto/openssl 在RK3288上的编译以及MQTT客户端的代码示例

    1,依赖库openssl 的交叉编译 (1)配置编译器信息 setarch i386 ./config no-asm shared --cross-compile-prefix=arm-linux-a ...

随机推荐

  1. vue-cli 构建vue项目

    师父说,咱们还是要用vue-cli 去构建前端项目.然后我就开始了 懵逼之旅. 今天上午主要就是搞懂用webpack和vue-cli怎么搭建 运行项目 首先找到了咱们博客园 园友的博客,提供了大概五个 ...

  2. libjpeg用法

    libjpeg是一个完全用C语言编写的库,包含了被广泛使用的JPEG解码.JPEG编码和其他的JPEG功能的实现.这个库由独立JPEG工作组维护.最新版本号是6b,于1998年发布.可以参考维基百科关 ...

  3. autohotkey 自动登录输入用户名密码 getElementsByTagName/getElementsByClassName/getElementById

    针对button未设置id的.可以通过getElementsByTagName获取button的对象数组,再明确其在对象数组中的位置,如第4个button,通过[3]获取.再调用此对象的click() ...

  4. js 第四章 cookie的操作

    js 第四章 cookie的操作 一.学习要点 掌握cookie的简单应用 二. js 第四章 cookie的操作 了解cookie 什么是cookie? cookie 是存储于访问者的计算机中的变量 ...

  5. js进阶解决浏览器缓存不能自动更新的问题(在ajax的url上带上一个参数,可以是日期,或者是随机数)(随机数Math.random)(取得日期的毫秒数:new Date().getTime();)

    js进阶解决浏览器缓存不能自动更新的问题(在ajax的url上带上一个参数,可以是日期,或者是随机数)(随机数Math.random)(取得日期的毫秒数:new Date().getTime();) ...

  6. 使用ionic3快速开发webapp(一)

    Ionic可以让我们使用web技术快速构建接近原生体验的跨平台移动应用. 一.安装ionic 1.需要先安装 Node.js(版本8.x之上): 2.安装cordova 和 ionic: $ npm ...

  7. 该扩展程序未列在 Chrome 网上应用店中,并可能是在您不知情的情况下添加的

    "chrome扩展程序无法启用"的解决方案 http://www.cnplugins.com/tool/installpluginfix.html win10家庭版没有组策略怎么办? https:// ...

  8. 魔兽争霸war3心得体会(四):不死族vs人族1本火魔塔

    QQ对战平台上玩随机的人特别多,为了应对对方的"出其不意",我最近一直用小狗去探路,小狗在家采集30个木头-摆放商店,就可以去探路了.主要有几个好处:知道对方的种族-出生点位-开局 ...

  9. 微擎 plugin 时间插件 图片上传插件不显示 报错 影响下面执行

    可能是版本更新导致的,之前可能不需要 load()->func('tpl');这个方法 现在加上 load()->func('tpl');应该就可以了

  10. Jcaptca 图片

    http://www.oschina.net/code/snippet_89964_6009 http://blog.csdn.net/tender001/article/details/846969 ...