ESP32 BLE学习(1) — GAP和GATT回调函数作用

前言

(1)学习本文之前,需要先了解的基础知识:ESP32 BLE学习(0) — 基础架构
(2)该部分只是对GAPGATT回调函数进行简单的介绍,因为这两个回调函数中参数太多,个人认为没必要全部进行讲解。因此只有当我认为需要使用的时候,才会讲解对应的内容。

回调函数作用介绍

(1)在学习蓝牙基础架构的时候,我们知道GAP主要用来进行广播,扫描和发起连接等。而GATT用来规范属性(Attribute)中的数据内容,并运用分组(group)的概念对属性(Attribute)进行分类管理。
(2)在ESP32中,GAPGATT的所有操作将分别在esp_ble_gatts_register_callback()esp_ble_gap_register_callback()这两个函数注册的回调函数中进行。

    // 注册 GATT 回调函数,处理所有的 GATT 事件ret = esp_ble_gatts_register_callback(gatts_event_handler);if (ret){ESP_LOGE(GATTS_TABLE_TAG, "gatts register error, error code = %x", ret);return;}// 注册 GAP 回调函数,ret = esp_ble_gap_register_callback(gap_event_handler);if (ret){ESP_LOGE(GATTS_TABLE_TAG, "gap register error, error code = %x", ret);return;}

(3)在这两个回调函数中的类型如下:

// GATT 回调函数
typedef void (* esp_gatts_cb_t)(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
// GAP 回调函数
typedef void (* esp_gap_ble_cb_t)(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);

回调函数参数具体分析

GATT回调函数

esp_gatts_cb_event_t结构体

(1)esp_gatts_cb_event_t就是一个enmu枚举参数。当出现对应的GATT事件的时候,底层协议栈就会触发GATT回调函数,并将对应事件以esp_gatts_cb_event_t枚举形式进行通知。
(2)接下来我将会讲解常见的几种GATT事件及其如何进行触发。

  • ESP_GATTS_REG_EVT : 当调用 esp_ble_gatts_app_register() 函数注册应用ID触发该事件。
  • ESP_GATTS_READ_EVT :当客户端发送读命令,ESP32作为服务端将会触发该事件。
  • ESP_GATTS_WRITE_EVT : 当客户端发送一个写请求并且写的数据<=(MTU-3)ESP32作为从设备将会触发该事件。
  • ESP_GATTS_EXEC_WRITE_EVT : 当客户端发送一个写请求并且写的数据>(MTU-3)ESP32作为从设备将会触发该事件。
  • ESP_GATTS_MTU_EVT :当客户端发送设置MTU请求时,ESP32作为服务端触发该事件。
  • ESP_GATTS_CONF_EVT : 当ESP32作为服务端收到客户端对之前发送的指示(Indication)或通知(Notification)的确认时,就会触发该事件。
  • ESP_GATTS_START_EVT : 当ESP32作为服务端成功启动,该事件触发。
  • ESP_GATTS_CONNECT_EVT : 当客户端发起连接事件,ESP32作为服务端,该事件触发。
  • ESP_GATTS_DISCONNECT_EVT : 当客户端断开连接,ESP32作为服务端,该事件触发。
  • ESP_GATTS_CREAT_ATTR_TAB_EVTesp_ble_gatts_create_attr_tab() 创建 GATT 完成时触发该事件。

esp_gatt_if_t

(1)这其实就是一个无符号的8bit数据,它用于标识不同的GATT客户端,该参数与esp_ble_gatts_app_register()函数注册的app_id成对应关系。
(2)当我们调用esp_ble_gatts_app_register()函数注册的app_id时候,协议栈会为其分配一个对应的 gatts_if,用于标识一个 GATT 服务。同时会触发esp_ble_gatts_register_callback() 注册的回调函数中的 ESP_GATTS_REG_EVT 事件。

typedef uint8_t    esp_gatt_if_t;   

esp_ble_gatts_cb_param_t结构体

(1)esp_ble_gatts_cb_param_t是一个联合体,该联合体和esp_gatts_cb_event_t这个enmu枚举参数是存在对应关系的。
(2)如下为对应图:

/* --- ESP_GATTS_REG_EVT --- */
param->reg.status // 注册应用ID的操作状态
param->reg.app_id // esp_ble_gatts_app_register()注册函数中输入的app_id
/* --- ESP_GATTS_READ_EVT --- */
param->read.conn_id // GATT读事件的连接ID,用于标识当前读取操作所涉及的连接的唯一标识符
param->read.trans_id // 确保了每个读操作的事务一致性,防止响应被错误地关联到其他读请求
param->read.bda // 写入的蓝牙设备地址
param->read.handle // GATT 句柄
param->read.offset // 如果需要读取的值太长,该值为偏移量
param->read.is_long // 需要读取的值是否过长,与.offset进行配合
param->read.need_rsp // 该写操是否需要回复
/* --- ESP_GATTS_WRITE_EVT --- */
param->write.conn_id // GATT写事件的连接ID,用于标识当前写操作所涉及的连接的唯一标识符
param->write.trans_id // 确保了每个写操作的事务一致性,防止响应被错误地关联到其他读请求
param->write.bda // 要被写入的蓝牙设备地址
param->write.handle // GATT 句柄
param->write.offset // 如果需要写的值太长,该值为偏移量
param->write.need_rsp // 该写操是否需要回复
param->write.is_prep // GATT(通用属性配置文件)服务器的写入操作是否为预备写入(Prepare Write)
param->write.len // 该写操作的值长度
param->write.value // 该写操作的值
/* --- ESP_GATTS_EXEC_WRITE_EVT --- */
param->exec_write.conn_id // 连接ID
param->exec_write.trans_id // 传递ID
param->exec_write.bda // 要被写入的蓝牙设备地址
param->exec_write.exec_write_flag // 执行写标志
/* --- ESP_GATTS_MTU_EVT --- */
param->mtu.conn_id // 连接ID
param->mtu.mtu // MTU大小
/* --- ESP_GATTS_CONF_EVT --- */
param->conf.status  // 客户端的确认状态
param->conf.conn_id // 连接ID
param->conf.handle  // GATT句柄
param->conf.len     //  指示(Indication)或通知(Notification)的值长度,在发送指示(Indication)或通知(Notification)失败的时候,该值有效
param->conf.value   // 指示(Indication)或通知(Notification)的值,在发送指示(Indication)或通知(Notification)失败的时候,该值有效
/* --- ESP_GATTS_START_EVT --- */
param->start.status         // GATT服务启动状态
param->start.service_handle // GATT服务句柄
/* --- ESP_GATTS_CONNECT_EVT --- */
param->connect.conn_id       // 连接ID
param->connect.link_role     // 链路层角色,0标识主设备,1标识从设备
param->connect.remote_bda    // 对端蓝牙地址
param->connect.conn_params   // 当前的连接参数
param->connect.ble_addr_type // 对端蓝牙设备地址类型
param->connect.conn_handle   // HCI层连接句柄
/* --- ESP_GATTS_DISCONNECT_EVT --- */
param->disconnect.conn_id    // 连接ID
param->disconnect.remote_bda // 对端蓝牙设备地址
param->disconnect.reason     // 蓝牙断连原因
/* --- ESP_GATTS_CREAT_ATTR_TAB_EVT --- */
param->add_attr_tab.status      // GATT服务创建状态
param->add_attr_tab.svc_uuid    // 创建的GATT服务UUID类型,有16bit、32bit、128bit
param->add_attr_tab.svc_inst_id // 创建的GATT服务UUID ID号
param->add_attr_tab.num_handle  // 要添加到GATT数据库的属性句柄编号
param->add_attr_tab.handles     // GATT句柄编号

GAP回调函数

esp_gap_ble_cb_event_t

(1)esp_gap_ble_cb_event_t就是一个enmu枚举参数。当出现对应的GAP事件的时候,底层协议栈就会触发GAP回调函数,并将对应事件以esp_gap_ble_cb_event_t枚举形式进行通知。
(2)接下来我将会讲解常见的几种GAP事件及其如何进行触发。

  • ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT : 当调用 esp_ble_gap_config_adv_data_raw() 函数设置了广播包成功后触发该事件。
  • ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT : 当调用 esp_ble_gap_config_scan_rsp_data_raw() 函数设置了广播扫描响应包成功后触发该事件。
  • ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT : 当调用 esp_ble_gap_config_adv_data() 函数,其中.set_scan_rsp = false设置广播包成功后触发该事件。
  • ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT : 当调用 esp_ble_gap_config_adv_data() 函数,其中.set_scan_rsp = true设置广播扫描响应包成功后触发该事件。
  • ESP_GAP_BLE_ADV_START_COMPLETE_EVT : 当调用esp_ble_gap_start_advertising()函数成功启动广播之后触发该事件。
  • ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT : 当调用esp_ble_gap_stop_advertising()函数成功启动广播之后触发该事件。不过在BLE5.0之后的广播包在连接时有ESP_GAP_BLE_ADV_TERMINATED_EVT事件报上来。
  • ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT : 很多应用场景中,从设备主设备刚建立连接时,会使用“快速”的连接参数以达到迅速交换信息的目的,但是,从设备主设备机之间并不是一直需要快速的交换信息,因为这样会加快从机电池能量的消耗,这时候,从设备就希望能降低连接事件的频度(连接间隔),从而降低功耗,延长电池工作时间。因此,这里从设备就可以向主设备发起链路层连接参数更新控制(Connection Parameter Update Control)。连接参数更新成功,那么该事件就会被触发。

esp_ble_gap_cb_param_t

(1)esp_ble_gap_cb_param_t是一个联合体,该联合体和esp_gap_ble_cb_event_t这个enmu枚举参数是存在对应关系的。
(2)如下为对应图:

/* --- ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT --- */
param->adv_data_raw_cmpl.status // 设置广播包操作成功状态
/* --- ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT --- */
param->scan_rsp_data_raw_cmpl.status // 设置扫描回应包操作成功状态
/* --- ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT --- */
param->adv_data_cmpl.status // 设置广播包操作成功状态
/* --- ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT --- */
param->scan_rsp_data_cmpl.status // 设置扫描回应包操作成功状态
/* --- ESP_GAP_BLE_ADV_START_COMPLETE_EVT --- */
param->adv_start_cmpl.status // 设置广播开始操作成功状态
/* --- ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT --- */
param->adv_stop_cmpl.status // 设置广播停止操作成功状态
/* --- ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT --- */
param->update_conn_params.status   // 设置连接更新参数操作成功状态
param->update_conn_params.bda      // 蓝牙设备地址
param->update_conn_params.min_int  // 最小连接间隔
param->update_conn_params.max_int  // 最大连接间隔
param->update_conn_params.latency  // 从机连接延迟时间(以连接事件数为单位)。范围:0x0000 ~ 0x01F3
param->update_conn_params.conn_int // 当前连接间隔
param->update_conn_params.timeout  // LE Link的监督超时。取值范围:0x000A ~ 0x0C80。Time = N * 10 msec

参考

(1)乐鑫官方文档
(2)乐鑫官方论坛:Write a string to characteristic

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/855502.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Llama 3 大型语言模型到底是如何炼成的?

Meta 在今年 4 月开源了 Llama 3 大型语言模型&#xff0c;这是 Meta&#xff0c;也是整个行业迄今为止功能最强大的开源 LLM。 那么 Meta 是如何训练 Llama 3 大型语言模型的&#xff0c;又在训练过程中遇到了什么问题&#xff0c;提出了什么新的解决方案呢&#xff1f;近日&…

计算机行业的现状与未来之2024

年年都说编程好&#xff0c;编程工资涨不了。 人家骑车送外卖&#xff0c;月入两万好不好。 一、计算机专业的背景与现状 在过去几十年里&#xff0c;计算机科学相关专业一直是高考考生的热门选择。无论是计算机科学与技术、软件工程&#xff0c;还是人工智能与大数据&#xff…

防止员工离职导致数据泄露,员工离职后把文件带出公司

中科数安的电脑文件资料透明加密防泄密系统确实能够在一定程度上防止员工离职导致的数据泄露。以下是具体的分析&#xff1a; www.weaem.com 访问控制与权限管理&#xff1a;系统实施了严格的权限管理制度&#xff0c;对核心文件和数据资源进行细致的访问权限划分。这意味着&am…

《无与伦比》Centos7 扩容到已有逻辑卷

命令可以查找硬盘和分区情况 fdisk -l lsblk

掌握市场脉动,Anzo Capital深度解析随机指标的超买超卖秘密

随机指标&#xff0c;作为市场分析的利器&#xff0c;主要用于判断资产价格的相对位置&#xff0c;是揭示市场超买与超卖状态的关键工具&#xff0c;也是大多数交易平台的标准配置。它以独特的视角&#xff0c;帮助交易者捕捉市场的微妙变化。下面跟随Anzo Capital视角&#xf…

leetcode (top100)接雨水

题目&#xff1a; 题解&#xff1a; 可以把每个宽度看作一个桶&#xff0c;每个桶能接的水等于这个桶左右两个方向最高桶的最小高度再减去这个桶本身的高度。把每个桶能接的水相加即可。 难点在于如何快速找到当前桶的左右两个方向的最高桶的高度&#xff0c;可以先遍历一遍…

数据库物理计划执行指南

一、背景介绍 伴随信息技术地迅猛发展和应用范围地逐步扩大&#xff0c;数据库已成为企业存储与管理数据的重要工具。但数据量激增以及用户访问需求的与日剧增&#xff0c;数据库性能也将面临巨大挑战。 好在数据库物理计划执行是解决数据库性能问题的重要手段之一&#xff0…

IMP和引用码 位置关系

基础类搭建 IMP和引用码位置 无限制 取决于&#xff08;&#xff08;地址转发机制&#xff09;组 分析&#xff09; 地址(消息)转发机制&#xff1a;1.子层IMP可由父层内引用码触发2.子层IMP可由子层内引用码触发 3.父层IMP可由子层内引用码触发4.父层IMP可由父层内引用码触发…

【技巧】Leetcode 201. 数字范围按位与【中等】

数字范围按位与 给你两个整数 left 和 right &#xff0c;表示区间 [left, right] &#xff0c;返回此区间内所有数字 按位与 的结果&#xff08;包含 left 、right 端点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;left 5, right 7 输出&#xff1a;4 解题思路 …

【面试实战】# 并发编程

1.线程状态 请解释 Java 中线程的几种状态&#xff0c;并描述每种状态的特点和转换条件。 NEW&#xff08;新建&#xff09;&#xff1a;线程被创建&#xff0c;但尚未启动。RUNNABLE&#xff08;可运行&#xff09;&#xff1a;线程正在运行&#xff0c;可能在执行代码&#x…

Maria/Mysql部署时远程连不上主机

‘主机’ is not allowed to connect to this MariaDB . 原因是设置为仅本机登录。 以root用户登录 -- 使用mysql库 use mysql; -- 查看可以登录的用户 select host,user,password from user; -- 修改root可以在任意主机登录(注意user) update user set host % where user r…

看门狗 WDG

嵌入式软件中的看门狗&#xff08;Watchdog Timer, WDT&#xff09;是一种监控机制&#xff0c;用于确保系统在出现故障时能够自动恢复正常运行。它通常由硬件定时器和相应的软件组成&#xff0c;当系统中的软件没有在预定时间内喂狗&#xff08;即重置定时器&#xff09;时&am…

Ansible Automation Platform(RHAAP2)架构中的四种节点及配置

在清单文件inventory中配置 #自动化控制节点设置 [automationcontroller] example.com #默认为混合节点 control.example node_typecontrol #作为控制节点&#xff0c;仅负责自动化的平台运行 hybrid.example node_typehybrid #作为混合节点&#xff0c;即是自动化平台又是任…

手机号码的校验

手机号码的校验 手机号码的校验应用的场景还是很多的&#xff0c;也随处可见&#xff0c;下面就记录几个校验方法 const emptyTip 请输入; // 必选项为空 const patternTip 请输入正确的; // 格式错误 // 联系电话校验&#xff08;固话手机&#xff09; /(^0\d{2,3}-?\d{7,8…

服务器数据恢复—KVM虚拟机被误删除如何恢复虚拟磁盘文件?

服务器数据恢复环境&故障&#xff1a; 1台服务器&#xff0c;Linux操作系统EXT4文件系统&#xff0c;部署了数台KVM虚拟机&#xff0c;每台虚拟机包含一个qcow2格式的磁盘文件&#xff0c;和一个raw格式的磁盘文件。 工作人员操作失误删除了3台服务器上的KVM虚拟机&#xf…

一站式的ITO服务,涵盖了业务流程外包(BPO)、IDC驻场运维以及IDC工程实施等三大类别

在信息技术日新月异的今天&#xff0c;企业对于信息技术服务外包&#xff08;ITO服务&#xff09;的需求日益增加。联通作为领先的通信服务提供商&#xff0c;凭借其在信息技术领域的深厚积累&#xff0c;为客户提供了一站式的ITO服务&#xff0c;涵盖了业务流程外包&#xff0…

13.4 内存管理

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

【课程系列04】某客时间AI大模型应用开发实战营

网盘链接 https://pan.baidu.com/s/1blR1eIMDIIp6AbxU4YaK9w 课程收获 "AI大模型应用开发实战营"是一个为期八周的在线课程&#xff0c;旨在教授学员如何开发和应用AI大模型。课程内容从基础理论到实际应用&#xff0c;逐步深入&#xff0c;覆盖了以下要点&#x…

python发邮件给多人的注意事项?如何群发?

python发邮件给多人的效率如何&#xff1f;python发邮件的方法&#xff1f; 在利用Python编程语言实现邮件群发功能时&#xff0c;需要注意许多细节&#xff0c;以确保邮件能有效送达且用户体验良好。AokSend将详细探讨python发邮件给多人时需要注意的各个方面&#xff0c;以帮…

Python邮件加密传输如何实现?有哪些技巧?

Python邮件怎么设置服务器&#xff1f;如何使用Python发送邮件&#xff1f; 为了确保邮件内容在传输过程中不被窃听或篡改&#xff0c;使用加密传输是必不可少的。在使用Python邮件传输时&#xff0c;加密传输是保障信息安全的关键手段。AokSend将详细探讨Python邮件加密传输的…