CC2541解析广播数据及扫描响应

广播数据(advertData)和扫描响应(scanRspData)

在典型的蓝牙BLE(Bluetooth Low Energy )系统中,从机设备广播数据让所有主机设备知道它是一个可连接的设备。接收到广播数据的主机,发送一个扫描请求(scan request)给从机,从机再返回扫描请求。

首先看一下广播数据,下面是广播包的数据定义:

static uint8 advertData[] =
{
  // Flags; this sets the device to use limited discoverable
  // mode (advertises for 30 seconds at a time) instead of general
  // discoverable mode (advertises indefinitely)
  0x02,   // length of this data
  GAP_ADTYPE_FLAGS,
  DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,

  // in this peripheral
  0x1A,   // length of this data 26byte
  GAP_ADTYPE_MANUFACTURER_SPECIFIC,  
  /*Apple Pre-Amble*/
  0x4C,
  0x00,
  0x02,
  0x15,
  /*Device UUID (16 Bytes)*/
  0x4A, 0xA8, 0x31, 0x6E, 0x88, 0xE8, 0x96, 0x78, 0xCA, 0x74, 0xDE, 0x07, 0x19, 0x8A, 0xB3, 0x9B,
//  0x2A, 0x97, 0x20, 0x4E, 0x68, 0xB8, 0x86, 0x18, 0xC8, 0x34, 0xDD, 0x67, 0x79, 0x85, 0x43, 0x8B,
//0xe2,  0xc5,   0x6d,   0xb5,  0xdf,   0xfb,  0x48, 0xd2,   0xb0,   0x60,  0xd0,  0xf5,  0xa7,  0x10,  0x96,  0xe0,
  /*Major Value (2 Bytes)*/
  0x00,0x00,    
  
  /*Minor Value (2 Bytes)*/
  0x00,0x00,  
  
  /*Measured Power*/
  0xCD
};
advertData[] 数组中第一个字节 0x1A 代表此段数据的长度,第二个字节为广播的数据模式,从第三个字节到第一个字节指定的长度为止,为有效的数据。以此类推。此广播数据中包含了从设备的广播模式和 UUID 这个是ibeacon的广播数据定义。

扫描响应的数据定义如下:

// GAP - SCAN RSP data (max size = 31 bytes)
static uint8 scanRspData[] =
{
  // complete name
  0x05,   // length of this data
  GAP_ADTYPE_LOCAL_NAME_COMPLETE,
    'N',  'A',  'M',  'E',
  // connection interval range
  0x05,   // length of this data
  GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
  LO_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),   // 100ms
  HI_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),
  LO_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),   // 1s
  HI_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),

  // Tx power level
  0x02,   // length of this data
  GAP_ADTYPE_POWER_LEVEL,
  0       // 0dBm
};
我们平时打开手机扫描蓝牙设备时扫描到的设备的名字,就是在这里进行定义的,所以如果 想获取设备名称,就要获得扫描回应 scanRspData[] 的数据,并从中分离出类型为 GAP_ADTYPE_LOCAL_NAME_COMPLETE 的数据。

那么,如何解析广播数据和扫描响应包呢?

主机回调函数simpleBLECentralEventCB( gapCentralRoleEvent_t *pEvent )是当发生某一件事时调用的函数,当相应事件发生时,分析出是哪个事件并进行相应的处理。GAP_DEVICE_INFO_EVENT是获取从机设备信息的处理事件,GAP_DEVICE_DISCOVERY_EVENT是设备发现事件。在GAP_DEVICE_INFO_EVENT事件中有两个不同数据,广播数据和扫描回应数据,这就是我们要解析的部分。我们先来看一下主机回调函数simpleBLECentralEventCB( gapCentralRoleEvent_t *pEvent )传递的gapCentralRoleEvent_t的参数指针。其结构为:

/**
 * Central Event Structure
 */
typedef union
{
  gapEventHdr_t             gap;                //!< GAP_MSG_EVENT and status.
  gapDeviceInitDoneEvent_t  initDone;           //!< GAP initialization done.
  gapDeviceInfoEvent_t      deviceInfo;         //!< Discovery device information event structure.
  gapDevDiscEvent_t         discCmpl;           //!< Discovery complete event structure.
  gapEstLinkReqEvent_t      linkCmpl;           //!< Link complete event structure.
  gapLinkUpdateEvent_t      linkUpdate;         //!< Link update event structure.
  gapTerminateLinkEvent_t   linkTerminate;      //!< Link terminated event structure.
} gapCentralRoleEvent_t;
其中有一个deviceInfo成员,为设备信息相关的数据,其类型为gapDeviceInitDoneEvent_t,结构定义如下:
<pre name="code" class="cpp">/**
 * GAP_DEVICE_INFO_EVENT message format.  This message is sent to the
 * app during a Device Discovery Request, when a new advertisement or scan
 * response is received.
 */
typedef struct
{
  osal_event_hdr_t  hdr;    //!< GAP_MSG_EVENT and status
  uint8 opcode;             //!< GAP_DEVICE_INFO_EVENT
  uint8 eventType;          //!< Advertisement Type: @ref GAP_ADVERTISEMENT_REPORT_TYPE_DEFINES
  uint8 addrType;           //!< address type: @ref GAP_ADDR_TYPE_DEFINES
  uint8 addr[B_ADDR_LEN];   //!< Address of the advertisement or SCAN_RSP
  int8 rssi;                //!< Advertisement or SCAN_RSP RSSI
  uint8 dataLen;            //!< Length (in bytes) of the data field (evtData)
  uint8 *pEvtData;          //!< Data field of advertisement or SCAN_RSP
} gapDeviceInfoEvent_t;

 

在这个结构体里,有定义广播的类型,以及具体指向广播数据或者扫描响应数据段的指针和数据长度。我们可以通过eventType来区分*pEvtData的数据具体为广播数据还是扫描响应数据。通过主机回调函数simpleBLECentralEventCB( gapCentralRoleEvent_t *pEvent ),我们再进一步来解析eventType和*pEvtData。

case GAP_DEVICE_INFO_EVENT:
      {
       if(pEvent->deviceInfo.eventType == GAP_ADRPT_SCAN_RSP )       //scan_rsp
        {
           pEvent->deviceInfo.dataLen;                               //扫描回应数据长度
           pEvent->deviceInfo.pEvtData;                              //扫描回应数据
        }
        if(pEvent->deviceInfo.eventType == GAP_ADRPT_ADV_IND )       //adv
        {
           pEvent->deviceInfo.dataLen;                               //广播数据长度
           pEvent->deviceInfo.pEvtData;                              //广播数据
        }
      }
Break;

欢迎大家扫描下方二维码关注我的个人微信公众号,一起交流学习,谢谢。



  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值