以下代码将用最简单的方式来展示 GATT 广播流程。
此方式并非适用于生产环境,仅仅用来理解
ESP32
的蓝牙非定向广播流程。
首先,包含广播程序需要的头文件
#include "esp_log.h"
#include "esp_err.h"
#include "nvs_flash.h"
#include "esp_bt.h" /* For bluetooth controller */
#include "esp_bt_main.h" /* For bluedroid stack */
#include "esp_gap_ble_api.h" /* For GAP */
首先包含需要的头文件。
设置需要的宏
#define ADVERTISING_TEST_TAG "ADVERTISING TEST"
#define DEVICE_NAME "Moker's ESP32"
ADVERSITING_TEST_TAG
: 为ESP_LOGI()/ESP_LOGE()
函数提供一个打印标识。DEVICE_NAME
: 设置设备名称。
编写 ESP32 的 app_main()
入口函数
打印自定义内容
ESP_LOGI(ADVERTISING_TEST_TAG, "--------------------------");
ESP_LOGI(ADVERTISING_TEST_TAG, "| Advertising test start |");
ESP_LOGI(ADVERTISING_TEST_TAG, "--------------------------");
定义接收函数返回值的变量
esp_err_t ret;
- 此变量用来接收函数的返回值,从而判断函数执行状态。
初始化 nvs flash
/* Initialize flash */
ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret = ESP_ERR_NVS_NEW_VRESION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
ESP_LOGI(ADVERTISING_TEST_TAG, "Initialized nvs flash.");
通过初始化操作,判断 nvs flash 中是否任存在空间,或者检查到新版本的 nvs flash ,则擦除整个 nvs flash,并重新初始化。
- 有关 nvs flash 的详细内容,可在官网查询资料。
释放经典蓝牙控制器内存
ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
初始化蓝牙控制器参数为缺省配置
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
初始化蓝牙控制器(物理层)
/* Initialize bluetooth controller */
ret = esp_bt_controller_init(&bt_cfg);
if (ret) {
ESP_LOGE(ADVERTISING_TEST_TAG, "Bluetooth controller initialize failed, error code = %x", ret);
return;
}
ESP_LOGI(ADVERTISING_TEST_TAG, "Initialized bluetooth controller.");
创建一个蓝牙控制器配置,用BT_CONTROLLER_INIT_CONFIG_DEFAULT()
缺省配置。
以低功耗模式启动蓝牙控制器(物理层)
/* Enable bluetooth controller */
ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
if (ret) {
ESP_LOGE(ADVERTISING_TEST_TAG, "Bluetooth controller enable failed, error code = %x", ret);
return;
}
ESP_LOGI(ADVERTISING_TEST_TAG, "Enabled bluetooth controller.");
启动蓝牙控制器,选择低功耗模式,为后续蓝牙协议栈做准备。
初始化蓝牙协议栈 bluedroid
/* Initialize bluedroid */
ret = esp_bluedroid_init();
if (ret) {
ESP_LOGI(ADVERTISING_TEST_TAG, "Bluedroid initialize failed, error code = %x", ret);
return;
}
ESP_LOGI(ADVERTISING_TEST_TAG, "Initialized bluedroid.");
启动 bluedroid 蓝牙协议栈
/* Enable bluedroid */
ret = esp_bluedroid_enable();
if (ret) {
ESP_LOGE(ADVERTISING_TEST_TAG, "Bluedroid enable failed, error code = %x", ret);
return;
}
ESP_LOGI(ADVERTISING_TEST_TAG, "Enabled bluedroid.");
设置设备名称
/* Set device name */
esp_ble_gap_set_device_name(DEVICE_NAME);
ESP_LOGI(ADVERTISING_TEST_TAG, "Set device name: \"%s\"", DEVICE_NAME);
设置原始广播数据
/* Config raw advertisement data */
static uint8_t raw_adv_data[] = {
0x02, 0x01, 0x06,
0x02, 0x0A, 0xEB,
0x03, 0x03, 0xAB, 0xCD
};
- 广播数据详解:[[8. GATT 广播数据]]
配置原始广播数据
ret = esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data));
if (ret) {
ESP_LOGE(ADVERTISING_TEST_TAG, "Config raw advertisement data failed, error code = %x", ret);
}
ESP_LOGI(ADVERTISING_TEST_TAG, "Configure raw advertisement data success.");
设置广播参数
/* Config advertising parameters */
static esp_ble_adv_params_t adv_params = {
.adv_int_min = 0x20,
.adv_int_max = 0x40,
.adv_type = ADV_TYPE_IND,
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
.channel_map = ADV_CHNL_ALL,
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};
开始广播
/* Start advertising */
while (true) {
ret = esp_ble_gap_start_advertising(&adv_params);
if (ret) {
ESP_LOGE(ADVERTISING_TEST_TAG, "Start advertising failed, erorr code = %x", ret);
}
ESP_LOGI(ADVERTISING_TEST_TAG, "Start advertising success.");
vTaskDelay(pdMS_TO_TICKS(100));
}
此处用一个无限循环来每隔 100ms 广播一次。