• 泰凌微蓝牙 HCI层事件的注册和使用


    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 具体数据格式和含义参考《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
    
    • 1
    • 2
    • 3
    • 4
    • 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    断开连接事件属于HCI事件中,所以这里以建立连接和断开连接的事件为例。泰凌微实际上自己定义了一些事件包括了连接和断开的事件,代码如下:

    bls_app_registerEventCallback (BLT_EV_FLAG_CONNECT, &task_connect);
    bls_app_registerEventCallback (BLT_EV_FLAG_TERMINATE, &task_terminate);
    
    • 1
    • 2

    但是这毕竟是泰凌微官方给的事件,我们还是想知道真正的蓝牙协议中是如何处理这个事件,还有原始的报文是什么样的。

    首先我们来看一下在Host或App层接收Controller HCI event的步骤

    1. 注册Controller HCI event的callback函数
    2. 打开对应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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    故需要执行以下代码:

    	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);
    
    • 1
    • 2
    • 3
    • 对于连接成功事件,它属于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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 相关阅读:
    小程序中Echarts实现隐藏x轴,y轴,刻度线,网格
    odoo 开发入门教程系列-约束(Constraints)
    Jenkins CVE-2017-1000353远程代码执行漏洞复现
    业务限制模型例题
    青出于“蓝”的合资第一新能源,“换壳”背后有门道
    4 搜索插入位置
    【英语:基础进阶_语法进阶提升】F4.名词性从句
    3个g的文件怎么发送给别人?三种方法自由选择!
    到底什么是UML?
    【Rust—LeetCode题解】1656. 设计有序流
  • 原文地址:https://blog.csdn.net/tilblackout/article/details/127906953