以下代码将用最简单的方式来展示 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: 设置设备名称。app_main()入口函数ESP_LOGI(ADVERTISING_TEST_TAG, "--------------------------");
ESP_LOGI(ADVERTISING_TEST_TAG, "| Advertising test start |");
ESP_LOGI(ADVERTISING_TEST_TAG, "--------------------------");
esp_err_t ret;
/* 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,并重新初始化。
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.");
启动蓝牙控制器,选择低功耗模式,为后续蓝牙协议栈做准备。
/* 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.");
/* 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
};
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 广播一次。