原创 【博客大赛】TI CC2541 BLE协议栈之Observer

2015-9-21 17:10 4057 19 19 分类: MCU/ 嵌入式 文集: CC254x蓝牙BLE4.0协议栈学习笔记

上一篇主要是研究了广播者(Broadcaster),现在再研究跟其“针锋相对”的观测者(Observer),我老觉得应该叫Scanner,扫描者,这样好像跟标准里的动词能对应上。

这里还是使用CC2541 BLE4.0协议栈(v1.4.0)中的例程,SimpleBLEObserver. 因为原例程是使用的TI官方的开发板,带LCD屏的,很多信息是显示在屏上。而笔者手头只有自己的一块板(做Observer)和TIkeyfob(做Broadcaster),所以笔者在例程中加入了UART的一些代码,以使信息显示在PC屏幕上。另外,扫描的启动和停止在原例程是上通过板上的按键触发,在这里同样使用UART,在PC上通过串口工具向CC2541发送字符‘S’表示启动和停止扫描(Start&Stop)。这部分功能在UART的中断里实现,代码片断如下:

#pragma vector = URX0_VECTOR

__interrupt void UART0_Isr(void)

{

  uint8 temp;

  temp = U0DBUF; 

  if(temp == 'S')

  {

           if ( !simpleBLEScanning )

           {

                   simpleBLEScanning = TRUE;

                   simpleBLEScanRes = 0;

                   GAPObserverRole_StartDiscovery( DEFAULT_DISCOVERY_MODE,

                                               DEFAULT_DISCOVERY_ACTIVE_SCAN,

                                               DEFAULT_DISCOVERY_WHITE_LIST );

           }

           else

           {

                   GAPObserverRole_CancelDiscovery();

           }

  } 

  URX0IF = 0;

}

 

对于Observer,要设置的主要参数有以下几个:

// Maximum number of scan responses

#define DEFAULT_MAX_SCAN_RES                  8

// Scan duration in ms

#define DEFAULT_SCAN_DURATION                 4000

// Discovey mode (limited, general, all)

#define DEFAULT_DISCOVERY_MODE                DEVDISC_MODE_ALL

注释也写得非常清楚,主要是最多进行扫描响应的个数、扫描时长及扫描的模式。

 

对于Observerobserver.hgap.h中的几个数据结构非常重要。

1

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.

} gapObserverRoleEvent_t;

这是一个联合,其中的gapDeviceInitDoneEvent_t是针对Observer自身的,gapDeviceInfoEvent_t是针对被扫描到的设备的,gapDevDiscEvent_t是针对扫描结果的。

2

/**

 * GAP_DEVICE_INIT_DONE_EVENT message format.  This message is sent to the

 * app when the Device Initialization is done [initiated by calling

 * GAP_DeviceInit()].

 */

typedef struct

{

  osal_event_hdr_t  hdr;              //!< GAP_MSG_EVENT and status

  uint8 opcode;                       //!< GAP_DEVICE_INIT_DONE_EVENT

  uint8 devAddr[B_ADDR_LEN];          //!< Device's BD_ADDR

  uint16 dataPktLen;                  //!< HC_LE_Data_Packet_Length

  uint8 numDataPkts;                  //!< HC_Total_Num_LE_Data_Packets

} gapDeviceInitDoneEvent_t;

主要是Observer自身的信息,比如自身的MAC等,在初始化结束后或有用。

3

/**

 * 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;

gapDeviceInfoEvent_t是关于被扫描到的设备的信息,笔者认为这应该是最重要的一个结构了。

其中的addr[]数组是被发现设备的MACrssi是信号强度,而后面的两个变量,dataLenpEvtData分别是上一篇中讲的scanRspData[]advertData[]的字节数和地址。可以编写函数将广播数据包及扫描应答数据包中的信息读出来。

这里笔者只把被扫描设备的MAC读了出来,转换成字符串显示在PC端。图中的0xBC6A29AB6588即为扫描到广播者的MAC地址。

20150921170952774001.jpg

文章评论0条评论)

登录后参与讨论
我要评论
0
19
关闭 站长推荐上一条 /2 下一条