Controler HCI event
是通过HCI将Controller所有的event报告给Host
HCI event
是按BLE Spec标准设计的,是BLE Controller和Host用来交互的事件;GAP event
是BLE host定义的一些协议栈流程交互时间通知型事件。
HCI event类型
#define HCI_EVT_DISCONNECTION_COMPLETE 0x05
#define HCI_EVT_ENCRYPTION_CHANGE 0x08
#define HCI_EVT_READ_REMOTE_VER_INFO_COMPLETE 0x0C
#define HCI_EVT_ENCRYPTION_KEY_REFRESH 0x30
#define HCI_EVT_LE_META 0x3E
- 具体数据格式和含义参考
《Core_v5.0》(Vol 2/Part E/7.7)
除了HCI_EVT_LE_META
,其他都要通过下面API来打开event mask
ble_sts_t blc_hci_setEventMask_cmd(u32 evtMask);
#define HCI_EVT_MASK_DISCONNECTION_COMPLETE 0x0000000010
#define HCI_EVT_MASK_ENCRYPTION_CHANGE 0x0000000080
#define HCI_EVT_MASK_READ_REMOTE_VERSION_INFORMATION_COMPLETE 0x0000000800
HCI_EVT_MASK_DISCONNECTION_COMPLETE
默认打开,保证断连事件的上报
HCI_EVT_LE_META
代表了HCI LE event
,它有一些subevent,常用的如下:
/* 当controller Link Layer和peer device建立connection,上报给Host */
#define HCI_SUB_EVT_LE_CONNECTION_COMPLETE 0x01
/* 当controller的Link Layer scan到正确的adv packet后 */
#define HCI_SUB_EVT_LE_ADVERTISING_REPORT 0x02
/* 当Controller上的connection update生效时 */
#define HCI_SUB_EVT_LE_CONNECTION_UPDATE_COMPLETE 0x03
/* Telink定义 */
#define HCI_SUB_EVT_LE_CONNECTION_ESTABLISH 0x20
例
断开连接事件属于HCI事件中,所以这里以建立连接和断开连接的事件为例。泰凌微实际上自己定义了一些事件包括了连接和断开的事件,代码如下:
bls_app_registerEventCallback (BLT_EV_FLAG_CONNECT, &task_connect);
bls_app_registerEventCallback (BLT_EV_FLAG_TERMINATE, &task_terminate);
但是这毕竟是泰凌微官方给的事件,我们还是想知道真正的蓝牙协议中是如何处理这个事件,还有原始的报文是什么样的。
首先我们来看一下在Host或App层接收Controller HCI event
的步骤
- 注册
Controller HCI event
的callback函数 - 打开对应event的mask
typedef int (*hci_event_handler_t) (u32 h, u8 *para, int n);
h:标记,底层协议栈多处会用到,user只需要以下两个:
#define HCI_FLAG_EVENT_TLK_MODULE (1<<24) //泰凌微自定义事件
#define HCI_FLAG_EVENT_BT_STD (1<<25) //表示当前event为Controller HCI event
para:event的数据
n:event的数据长度
void blc_hci_registerControllerEventHandler(hci_event_handler_t handler);
故需要执行以下代码:
blc_hci_registerControllerEventHandler(HCI_Event_Handler);
blc_hci_le_setEventMask_cmd(HCI_SUB_EVT_LE_CONNECTION_COMPLETE);
blc_hci_setEventMask_cmd(HCI_EVT_MASK_DISCONNECTION_COMPLETE);
- 对于连接成功事件,它属于
HCI_EVT_LE_META
事件的子事件,其中子事件编号为0x01时为连接成功事件 - 对于连接断开事件,它就是一个独立的事件,可以直接判断
现在我们需要实现HCI_Event_Handler
来处理产生的事件,加入我们连接成功要获得连接句柄connHandle
,我们来查询一下手册要怎么获取:
其中Octet为拉丁文,即字节,可以看到ConnHandle
在第三四字节,故代码如下:
int HCI_Event_Handler(u32 h, u8 *para, int n)
{
/* Controller HCI event */
if((h & HCI_EVT_LE_META) == HCI_EVT_LE_META)
{
/* HCI LE EVENT:通过subevent code判断 */
switch(para[0])
{
/* HCI_SUB_EVT_LE_CONNECTION_COMPLETE */
case 0x01:
{
connHandle = para[3]<<8 | para[2];
break;
}
default:
break;
}
}else if((h & HCI_EVT_DISCONNECTION_COMPLETE) == HCI_EVT_DISCONNECTION_COMPLETE)
{
/* 断开连接 */
}
return 1;
}