• 泰凌微蓝牙 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
  • 相关阅读:
    查找大于某个数的最小质数
    【CSS】div 盒子居中的常用方法
    第三章 内存管理 十一、虚拟内存的基本概念
    Object.prototype.toString.call() 和 instanceOf 和 Array.isArray() 详解
    如何使用 iMazing 3许可证激活软件及2024最新常见问题详细解答
    OFDM 十六讲 4 -What is a Cyclic Prefix in OFDM
    你们天天说的应用性能监控: Sky Walking
    大数据技术之Zookeeper总结Ⅰ
    Java 面试题集锦,横扫金九银十。
    ESP32-C3 基于Arduino框架下Blinker点灯控制10路开关或继电器组
  • 原文地址:https://blog.csdn.net/tilblackout/article/details/127906953