上一篇主要是研究了广播者(Broadcaster),现在再研究跟其“针锋相对”的观测者(Observer),我老觉得应该叫Scanner,扫描者,这样好像跟标准里的动词能对应上。
这里还是使用CC2541 BLE4.0协议栈(v1.4.0)中的例程,SimpleBLEObserver. 因为原例程是使用的TI官方的开发板,带LCD屏的,很多信息是显示在屏上。而笔者手头只有自己的一块板(做Observer)和TI的keyfob(做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
注释也写得非常清楚,主要是最多进行扫描响应的个数、扫描时长及扫描的模式。
对于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 [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[]数组是被发现设备的MAC,rssi是信号强度,而后面的两个变量,dataLen和pEvtData分别是上一篇中讲的scanRspData[]或advertData[]的字节数和地址。可以编写函数将广播数据包及扫描应答数据包中的信息读出来。
这里笔者只把被扫描设备的MAC读了出来,转换成字符串显示在PC端。图中的0xBC6A29AB6588即为扫描到广播者的MAC地址。
文章评论(0条评论)
登录后参与讨论