一天写了个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. Windows下安装Resin及配置具体解释与公布应用

        关于Resin的优点,网上介绍了一大堆.小编经不住诱惑,决定试用一下. 眼下Resin的最新版本号为:4.0.40.能够从官网直接下载.     1. 将下载下来的Resin包解压开,会看到一 ...

  2. 损失函数 - Andrew Ng机器学习公开课笔记1.2

    线性回归中提到最小二乘损失函数及其相关知识.对于这一部分知识不清楚的同学能够參考上一篇文章<线性回归.梯度下降>. 本篇文章主要解说使用最小二乘法法构建损失函数和最小化损失函数的方法. 最 ...

  3. php课程 8-32 如何使用gd库进行图片裁剪和缩放

    php课程 8-32 如何使用gd库进行图片裁剪和缩放 一.总结 一句话总结:图片缩放到图片裁剪就是改变原图截取的位置以及截取的宽高. 1.电商网站那么多的图片,如果全部加载卡得慢的很,所以他们是怎么 ...

  4. bootstrap课程4 bootstrap的css样式有哪些内容需要注意

    bootstrap课程4 bootstrap的css样式有哪些内容需要注意 一.总结 一句话总结: 1.如何选择产品(框架)的版本? 大版本下的最后一个版本,但是同时又要选择稳定的版本,也就是如果做产 ...

  5. 4、基于JZ2440之编写测试代码处理(处理图片识别人脸)

    1.代码如下: void detectAndDisplay(Mat image) { CascadeClassifier ccf; //创建脸部对象 //ccf.load(xmlPath); //导入 ...

  6. 全面详细介绍一个P2P网贷领域的ERP系统的主要功能

        一般的P2P系统,至少包括PC网站的前端和后端.前端系统的功能,可以参考"P2P系统哪家强,功能其实都一样" http://blog.csdn.net/fansunion/ ...

  7. ECMAScript5和ECMAScript6_浏览器支持情况

    ECMAScript5浏览器支持情况: Opera 11.60 Internet Explorer 9* Firefox 4 Safari 5.1** Chrome 13 * IE9不支持严格模式 - ...

  8. 原生js螺旋运动

    window.onload=function(){ var oSpiral=document.getElementById('spiral'); var oUl=oSpiral.getElements ...

  9. html表单元素及表单元素详解

    原文 https://www.jianshu.com/p/b427daa8663d 大纲 1.认识表单 2.认识表单元素 3.表单元素的分类 4.表单元素——文本框 5.表单元素button 6.表单 ...

  10. AngularJS之ng-options指令

    1.基本下拉效果(lable for value in array) 其中select标签中的ng-model属性必须有,其值为选中的对象或属性值. <div ng-controller=&qu ...