ESP32蓝牙开发笔记(一)

 ret = esp_ble_gap_register_callback(esp_gap_cb);
static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
    switch (event) {
    case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
        ESP_LOGI(CONN_TAG, "Advertising data set, status %d", param->adv_data_raw_cmpl.status);
        esp_ble_gap_start_advertising(&adv_params);
        break;
    case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
        if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) {
            ESP_LOGE(CONN_TAG, "Advertising start failed, status %d", param->adv_start_cmpl.status);
            break;
        }
        ESP_LOGI(CONN_TAG, "Advertising start successfully");
        break;
    case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
        if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS) {
            ESP_LOGE(CONN_TAG, "Advertising stop failed, status %d", param->adv_stop_cmpl.status);
        }
        ESP_LOGI(CONN_TAG, "Advertising stop successfully");
        break;
    case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
        ESP_LOGI(CONN_TAG, "Connection params update, status %d, conn_int %d, latency %d, timeout %d",
                    param->update_conn_params.status,
                    param->update_conn_params.conn_int,
                    param->update_conn_params.latency,
                    param->update_conn_params.timeout);
        break;
    default:
        break;
    }
}

1. ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT(广播数据设置完成事件)​

  • 触发条件:通过 esp_ble_gap_config_adv_data_raw() 设置原始广播数据完成后触发。
  • 处理逻辑
    • 检查广播数据配置状态(param->adv_data_raw_cmpl.status),若成功则调用 esp_ble_gap_start_advertising() 启动广播。
    • 关键作用:确保广播参数(如设备名称、UUID、广播间隔等)已正确加载后,再启动广播流程

2. ESP_GAP_BLE_ADV_START_COMPLETE_EVT(广播启动完成事件)​

  • 触发条件:调用 esp_ble_gap_start_advertising() 后,广播启动成功或失败时触发。
  • 处理逻辑
    • 检查状态码 param->adv_start_cmpl.status
      • 成功​(ESP_BT_STATUS_SUCCESS):记录广播启动成功日志。
      • 失败:记录错误原因(如参数不合法、资源冲突等),常见错误包括 ESP_ERR_INVALID_ARG(参数错误)或 ESP_FAIL(底层协议栈错误)
    • 典型应用:用于监控广播状态,确保设备可被发现。

3. ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT(广播停止完成事件)​

  • 触发条件:调用 esp_ble_gap_stop_advertising() 后,广播停止完成时触发。
  • 处理逻辑
    • 检查状态码 param->adv_stop_cmpl.status
      • 成功:记录停止成功日志。
    • 应用场景:在设备需要切换模式(如从广播模式转为连接模式)时调用。

4. ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT(连接参数更新事件)​

  • 触发条件:连接参数(如间隔、延迟、超时)通过 esp_ble_gap_update_conn_params() 更新后触发。
  • 处理逻辑
    • 输出更新后的连接参数:
      • ​**conn_int**:连接间隔(单位:1.25ms),影响通信频率与功耗。
      • ​**latency**:从机延迟(允许跳过的连接事件次数),用于平衡实时性与功耗。
    • 优化建议:根据业务需求调整参数,例如低功耗设备可增大连接间隔(如 40~100ms)

5. ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT(广播数据设置完成事件)​

  • 触发条件:通过 esp_ble_gap_config_adv_data() 或 esp_ble_gap_config_adv_data_raw() 设置广播数据完成后触发。
  • 处理逻辑
    • 检查状态码 param->adv_data_cmpl.status,若成功(ESP_BT_STATUS_SUCCESS),启动广播 esp_ble_gap_start_advertising()
    • 关键作用:确保广播数据(如设备名称、UUID、厂商自定义数据)已正确加载至协议栈。
  • 优化建议
    • 广播数据长度需符合 BLE 规范(≤31 字节),优先包含必要信息(如设备标识、服务 UUID)。
    • 若需动态更新广播内容(如传感器数据),可在此事件后重新配置数据并触发广播重启。

6. ESP_GAP_BLE_SCAN_RESULT_EVT(扫描结果事件)​

  • 触发条件:设备处于扫描模式时,每收到一个广播包触发一次。
  • 处理逻辑
    • 解析 param->scan_rst.ble_adv 中的广播数据,提取设备地址、RSSI、服务 UUID 等。
    • 示例代码:
      if (param->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) {
          esp_log_buffer_hex("SCAN", param->scan_rst.bda, 6); // 打印设备地址
          ESP_LOGI("SCAN", "RSSI: %d dBm", param->scan_rst.rssi);
      }
  • 优化建议
    • 使用过滤条件(如设备地址白名单、服务 UUID)减少无效扫描事件。
    • 在 ESP_GAP_SEARCH_INQ_CMPL_EVT(扫描完成事件)中统计设备列表并触发连接逻辑。

7. ESP_GAP_BLE_CONNECT_EVT(连接建立事件)​

  • 触发条件:与远端设备建立 BLE 连接后触发。
  • 处理逻辑
    • 保存连接句柄 param->connect.conn_id 和设备地址 param->connect.remote_bda
    • 关键操作:调用 esp_ble_gap_update_conn_params() 协商优化连接参数(如间隔、延迟)。
  • 优化建议
    • 低功耗设备可设置较大连接间隔(如 40-100ms),实时设备则减小间隔(如 7.5-20ms)。
    • 若连接参数更新失败(ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT 状态非零),触发重试或降级策略。

8. ESP_GAP_BLE_DISCONNECT_EVT(连接断开事件)​

  • 触发条件:BLE 连接因超时、主动断开或信号丢失等原因终止时触发。
  • 处理逻辑
    • 记录断开原因 param->disconnect.reason(如 ESP_HCI_ERR_CONN_TIMEOUT)。
    • 释放连接相关资源(如清空句柄、关闭 GATT 服务)。
    • 重连策略:调用 esp_ble_gap_start_advertising() 重新广播或主动扫描。
  • 优化建议
    • 根据业务场景选择断连行为:医疗设备立即重连,传感器可延迟重连以省电。
    • 结合 ESP_GAP_BLE_AUTH_CMPL_EVT 处理安全连接异常断开问题。

9. ESP_GAP_BLE_SEC_REQ_EVT(安全请求事件)​

  • 触发条件:远端设备请求加密或配对时触发。
  • 处理逻辑
    • 回复安全参数 esp_ble_gap_security_rsp(),选择加密模式(如 JUST_WORKS、PIN 输入)。
    • 示例:
      esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, true);
  • 优化建议
    • 医疗/金融设备启用 ESP_LE_AUTH_REQ_SC_MITM(MITM 保护)。
    • 低功耗设备可禁用加密(ESP_LE_AUTH_NO_BOND)以简化流程。

10. ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT(扫描停止完成事件)​

  • 触发条件:调用 esp_ble_gap_stop_scanning() 后触发。
  • 处理逻辑
    • 检查状态码 param->scan_stop_cmpl.status,失败时记录错误。
    • 释放扫描缓存或切换至连接/广播模式。
  • 优化建议
    • 合理设置扫描窗口(scan_window)与间隔(scan_interval),避免频繁启停。
    • 结合 ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT 动态调整扫描策略。

11. ESP_GAP_BLE_PHY_UPDATE_COMPLETE_EVT(物理层参数更新事件)​

  • 触发条件:通过 esp_ble_gap_set_prefer_phy() 更新 PHY 模式(如 1M/2M/Coded)后触发。
  • 处理逻辑
    • 解析 param->phy_update_cmpl.tx_phyrx_phy,确认新速率是否生效。
    • 示例:
      ESP_LOGI("PHY", "TX PHY: %s, RX PHY: %s", 
              get_phy_name(param->phy_update_cmpl.tx_phy),
              get_phy_name(param->phy_update_cmpl.rx_phy));
  • 优化建议
    • 室内环境使用 2M PHY 提升吞吐,远距离切换至 Coded PHY 增强信号。
    • 动态检测信号强度(RSSI),自动切换最佳 PHY 模式。
12. ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT(扫描参数设置完成事件)​
  • 触发条件:通过 esp_ble_gap_set_scan_params() 设置扫描参数(如间隔、窗口、过滤模式)后触发。
  • 处理逻辑
    • 检查状态码 param->scan_param_set_complete.status,若成功则启动扫描 esp_ble_gap_start_scanning()
    • 典型参数
      esp_ble_scan_params_t ble_scan_params = {
          .scan_type = BLE_SCAN_TYPE_ACTIVE,
          .scan_interval = 0x50,  // 50ms(0x50 * 0.625ms)
          .scan_window = 0x30,     // 30ms(0x30 * 0.625ms)
          .scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE
      };
    • 优化建议:短扫描窗口(如 30ms)降低功耗,长窗口(如 100ms)提升设备发现概率。
13. ESP_GAP_BLE_SCAN_RESULT_EVT(扫描结果事件)​
  • 触发条件:每收到一个广播包触发一次,需在 param->scan_rst.search_evt 中区分事件类型
    • ESP_GAP_SEARCH_INQ_RES_EVT:发现设备广播包。
    • ESP_GAP_SEARCH_INQ_CMPL_EVT:扫描完成。
  • 处理逻辑
    • 提取设备地址 scan_rst.bda、RSSI 信号强度 scan_rst.rssi
    • 解析广播数据 scan_rst.ble_adv(如设备名、服务 UUID)。
    • 示例
      case ESP_GAP_SEARCH_INQ_RES_EVT:
          ESP_LOGI("SCAN", "发现设备: %02X:%02X:%02X:%02X:%02X:%02X, RSSI: %d dBm",
                  scan_rst.bda[0], scan_rst.bda[1], scan_rst.bda[2],
                  scan_rst.bda[3], scan_rst.bda[4], scan_rst.bda[5],
                  scan_rst.rssi);
          break;
14. ESP_GAP_BLE_AUTH_CMPL_EVT(安全认证完成事件)​
  • 触发条件:BLE 配对或加密流程完成后触发。
  • 处理逻辑
    • 检查认证状态 param->auth_cmpl.success 和加密模式 param->auth_cmpl.auth_mode
    • 典型应用:记录设备绑定信息或处理认证失败重试逻辑。
15. ESP_GAP_BLE_SET_CHANNELS_EVT(信道分类设置事件)​
  • 触发条件:调用 esp_ble_gap_set_chnl_classify() 设置信道掩码后触发。
  • 关键参数
    • param->set_chnl_classify.channel_map:信道掩码(如 0x7FFFFFFF 表示启用所有 37 个 BLE 信道)。
  • 应用场景
    • 避免与 WiFi 信道冲突(如 BLE 信道 37-39 对应 WiFi 信道 1-6),减少干扰。
16. ESP_GAP_BLE_DATA_LENGTH_SET_COMPLETE_EVT(数据长度更新完成事件)​
  • 触发条件:调用 esp_ble_gap_set_data_length() 设置最大数据包长度后触发。
  • 关键参数
    • param->data_length_set_cmpl.max_tx_octets:单包最大数据长度(默认 27 字节,最大 251 字节)。
  • 应用场景
    • 增大数据包长度(如 251 字节)提升传输效率,适用于大数据传输(如固件升级)。 
17. ESP_GAP_BLE_KEY_EVT(密钥交换事件)​
  • 触发条件:配对过程中密钥生成或交换时触发。
  • 关键参数
    • param->ble_key.key_type:密钥类型(如临时密钥、长期密钥)。
    • param->ble_key.p_key_value:密钥值指针。
  • 防护建议
    • 启用 MITM(中间人保护)和 LE Secure Connections(安全连接)协议,防止密钥泄露。
18. ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT(解除绑定完成事件)​
  • 触发条件:调用 esp_ble_remove_bond_device() 删除绑定设备后触发。
  • 安全加固
    • 定期清理无效绑定信息,防止利用漏洞恢复历史绑定记录(如通过未公开命令绕过删除操作)。

你可能感兴趣的:(ESP32蓝牙开发,笔记)