1454|0

3836

帖子

19

TA的资源

纯净的硅(中级)

楼主
 

BLE蓝牙的数据黏包处理 [复制链接]

1.首先说明一下本文档的背景:

由于BLE蓝牙传输一个包最多只能18个字节,而实际通讯自己定的协议一般都会超过18个字节,而数据也一般会有非常多个包一起发送,这个时候很多包就会黏在一起,而其实最好最简单的处理方法就是,定义一个超大的buf,直接往buf里不断的往后黏,然后最后再将这个buf拿出来解析。但是呢,实际很多情况是需要实时处理蓝牙的数据,并将数据解析显示或者分析等,还有就是整个设备本身整个应用就是在传输中进行的,再者这个buf也是有限大小的,所以效率相当低下,且有一定局限性,遇到这种情况那就得边接收数据边解析处理数据,那么接下来就介绍对蓝牙黏包的处理。

  

2.蓝牙数据包的处理:

这个数据包处理主要是针对一款开锁器而设计的,所以里面设计了一个在线模式和离线模式的开锁,其他则与平时其他蓝牙应用的差不多。

流程图:



代码与解析:

uint8 incompleteFlag=0;//数据不完整标志

uint8 frontDataCount=0;//数据前半部分数量

uint8 backDataCount=18;//数据后半部分数量

uint8 totalDataCount=24;//实际协议数据包长度,这个根据自己定的协议而定

uint8_t tempString[24];//用的临时数组

uint8_t flashBuf[4800];//写入flash的数组

int flashBufLength=0;//flash数组的长度


SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR6,  newValue, &returnBytes);//接收到app端数据

      if(returnBytes > 0)//确认有数据

      {

          if(incompleteFlag!=0)//数据不完整

          {

              memcpy(tempString+backDataCount,newValue,frontDataCount);//将之前不足的6个字节补上(第一次为例)

              backDataCount=18-frontDataCount;//剩下12个字节

              //数据处理      

           if(tempString[5]==0x01&&tempString[0]==0x02&&tempString[1]==0x81)

              {

                //离线模式  将数据存入flash,根据是否写入flash成功进行回应

                if(flashBufLength==0)

                {

                   memcpy(flashBuf,tempString,totalDataCount);

                   flashBufLength+=totalDataCount;

                }

                else

                {

                   memcpy(flashBuf+flashBufLength,tempString,totalDataCount);

                   UART_WriteTransport(flashBuf, flashBufLength+totalDataCount);

                   flashBufLength+=totalDataCount;

                   //写入flash操作                                 

                }

                 //回应   

                  myRespondData[0]=0X01;

                  myRespondData[1]=0X01;

                  qq_write(myRespondData, 2);

                // 发送一个通知消息 SBP_UART_CHANGE_EVT, 以便把数据发送到空口

                  SimpleBLEPeripheral_enqueueMsg(SBP_UART_CHANGE_EVT, NULL);  

              }

              else

              {

                 //在线模式  将数据赋值给密码锁协议包直接下发,根据开锁是否成功进行回应


                //回应

                 myRespondData[0]=0X00;

                 myRespondData[1]=0X01;

              }


              if(returnBytes>=18)//还有数据

              {

                 memcpy(tempString,0,24);

                 memcpy(tempString,newValue+frontDataCount,backDataCount);//从新开始黏贴

                 frontDataCount=totalDataCount-backDataCount;

              }

              Else//没有数据了

              {

                 memcpy(tempString,0,24);

                 incompleteFlag=0;

                 frontDataCount=0;

                 backDataCount=18;

              }

          }

          else    //完整

          {

            if(newValue[0]==0x02&&newValue[1]==0x81)//如果头不符合则判定为错误数据

            {

              memcpy(tempString,newValue,backDataCount);//将18个字节直接黏到临时数组里

              frontDataCount=totalDataCount-backDataCount;//我的协议数组是24-18=6个字节还没有得到,要第二次接收才能得到(第一次为例)

            }

          }

           if(frontDataCount!=0)//零个字节没得到,则是完整数据

                incompleteFlag=1;

           else

                incompleteFlag=0;

      }      


此帖出自无线连接论坛
点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

开源项目 更多>>
    随便看看
    查找数据手册?

    EEWorld Datasheet 技术支持

    相关文章 更多>>
    关闭
    站长推荐上一条 1/10 下一条

     
    EEWorld订阅号

     
    EEWorld服务号

     
    汽车开发圈

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

    电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表