热度 19
2015-9-21 17:10
4054 次阅读|
0 个评论
上一篇主要是研究了广播者( Broadcaster ),现在再研究跟其“针锋相对”的观测者( Observer ),我老觉得应该叫 Scanner ,扫描者,这样好像跟标准里的动词能对应上。 这里还是使用 CC2541 BLE4.0 协议栈( v1.4.0 )中的例程, SimpleBLEObserver. 因为原例程是使用的 TI 官方的开发板,带 LCD 屏的,很多信息是显示在屏上。而笔者手头只有自己的一块板(做 Observer )和 TI 的 keyfob (做 Broadcaster ),所以笔者在例程中加入了 UART 的一些代码,以使信息显示在 PC 屏幕上。另外,扫描的启动和停止在原例程是上通过板上的按键触发,在这里同样使用 UART ,在 PC 上通过串口工具向 CC2541 发送字符‘ S ’表示启动和停止扫描( StartStop )。这部分功能在 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 注释也写得非常清楚,主要是最多进行扫描响应的个数、扫描时长及扫描的模式。 对于 Observer , observer.h 和 gap.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 . */ typedef struct { osal_event_hdr_t hdr; //! GAP_MSG_EVENT and status uint8 opcode; //! GAP_DEVICE_INIT_DONE_EVENT uint8 devAddr ; //! 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 ; //! 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 或 advertData[] 的字节数和地址。可以编写函数将广播数据包及扫描应答数据包中的信息读出来。 这里笔者只把被扫描设备的 MAC 读了出来,转换成字符串显示在 PC 端。图中的 0xBC6A29AB6588 即为扫描到广播者的 MAC 地址。