• 泰凌微蓝牙 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
  • 相关阅读:
    1921. 消灭怪物的最大数量
    树莓派SSH链接出错 Host key verification failed. 解决办法
    2023年(第六届)电力机器人应用与创新发展论坛-核心PPT资料下载
    java毕业设计房产交易系统Mybatis+系统+数据库+调试部署
    零代码编程:用ChatGPT批量合并文件夹
    Nmap常见用法
    linux文件组 avc: denied { dac_read_search } for capability=2
    Linux C进程间通信(IPC)
    CDR插件开发之Application(应用程序)
    拓尔微电子一站式提供中压18V 2A-6A Buck DC-DC转换器系列产品方案
  • 原文地址:https://blog.csdn.net/tilblackout/article/details/127906953