kopia lustrzana https://github.com/espressif/esp-idf
259 wiersze
9.0 KiB
C
259 wiersze
9.0 KiB
C
/*
|
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
|
|
|
Unless required by applicable law or agreed to in writing, this
|
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
CONDITIONS OF ANY KIND, either express or implied.
|
|
*/
|
|
|
|
/****************************************************************************
|
|
*
|
|
* This demo showcases BLE GATT server. It can send adv data, be connected by client.
|
|
* Run the gatt_client demo, the client demo will automatically connect to the gatt_server demo.
|
|
* Client demo will enable gatt_server's notify after connection. The two devices will then exchange
|
|
* data.
|
|
*
|
|
****************************************************************************/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "freertos/event_groups.h"
|
|
#include "esp_system.h"
|
|
#include "esp_log.h"
|
|
#include "nvs_flash.h"
|
|
#include "esp_bt.h"
|
|
|
|
#include "esp_gap_ble_api.h"
|
|
#include "esp_gatts_api.h"
|
|
#include "esp_bt_defs.h"
|
|
#include "esp_bt_main.h"
|
|
#include "esp_gatt_common_api.h"
|
|
|
|
#include "sdkconfig.h"
|
|
|
|
#include "freertos/semphr.h"
|
|
|
|
#define LOG_TAG "MULTI_ADV_DEMO"
|
|
|
|
#define FUNC_SEND_WAIT_SEM(func, sem) do {\
|
|
esp_err_t __err_rc = (func);\
|
|
if (__err_rc != ESP_OK) { \
|
|
ESP_LOGE(LOG_TAG, "%s, message send fail, error = %d", __func__, __err_rc); \
|
|
} \
|
|
xSemaphoreTake(sem, portMAX_DELAY); \
|
|
} while(0);
|
|
|
|
static SemaphoreHandle_t test_sem = NULL;
|
|
|
|
uint8_t addr_1m[6] = {0xc0, 0xde, 0x52, 0x00, 0x00, 0x01};
|
|
uint8_t addr_2m[6] = {0xc0, 0xde, 0x52, 0x00, 0x00, 0x02};
|
|
uint8_t addr_legacy[6] = {0xc0, 0xde, 0x52, 0x00, 0x00, 0x03};
|
|
uint8_t addr_coded[6] = {0xc0, 0xde, 0x52, 0x00, 0x00, 0x04};
|
|
|
|
esp_ble_gap_ext_adv_params_t ext_adv_params_1M = {
|
|
.type = ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE,
|
|
.interval_min = 0x30,
|
|
.interval_max = 0x30,
|
|
.channel_map = ADV_CHNL_ALL,
|
|
.filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
|
|
.primary_phy = ESP_BLE_GAP_PHY_1M,
|
|
.max_skip = 0,
|
|
.secondary_phy = ESP_BLE_GAP_PHY_1M,
|
|
.sid = 0,
|
|
.scan_req_notif = false,
|
|
.own_addr_type = BLE_ADDR_TYPE_RANDOM,
|
|
};
|
|
|
|
esp_ble_gap_ext_adv_params_t ext_adv_params_2M = {
|
|
.type = ESP_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE,
|
|
.interval_min = 0x40,
|
|
.interval_max = 0x40,
|
|
.channel_map = ADV_CHNL_ALL,
|
|
.filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
|
|
.primary_phy = ESP_BLE_GAP_PHY_1M,
|
|
.max_skip = 0,
|
|
.secondary_phy = ESP_BLE_GAP_PHY_2M,
|
|
.sid = 1,
|
|
.scan_req_notif = false,
|
|
.own_addr_type = BLE_ADDR_TYPE_RANDOM,
|
|
};
|
|
|
|
esp_ble_gap_ext_adv_params_t legacy_adv_params = {
|
|
.type = ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_IND,
|
|
.interval_min = 0x45,
|
|
.interval_max = 0x45,
|
|
.channel_map = ADV_CHNL_ALL,
|
|
.filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
|
|
.primary_phy = ESP_BLE_GAP_PHY_1M,
|
|
.max_skip = 0,
|
|
.secondary_phy = ESP_BLE_GAP_PHY_1M,
|
|
.sid = 2,
|
|
.scan_req_notif = false,
|
|
.own_addr_type = BLE_ADDR_TYPE_RANDOM,
|
|
};
|
|
|
|
esp_ble_gap_ext_adv_params_t ext_adv_params_coded = {
|
|
.type = ESP_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE,
|
|
.interval_min = 0x50,
|
|
.interval_max = 0x50,
|
|
.channel_map = ADV_CHNL_ALL,
|
|
.filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
|
|
.primary_phy = ESP_BLE_GAP_PHY_1M,
|
|
.max_skip = 0,
|
|
.secondary_phy = ESP_BLE_GAP_PHY_CODED,
|
|
.sid = 3,
|
|
.scan_req_notif = false,
|
|
.own_addr_type = BLE_ADDR_TYPE_RANDOM,
|
|
};
|
|
|
|
static uint8_t raw_adv_data_1m[] = {
|
|
0x02, 0x01, 0x06,
|
|
0x02, 0x0a, 0xeb,
|
|
0x11, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A',
|
|
'D', 'V', '_', '1', 'M'
|
|
};
|
|
|
|
static uint8_t raw_scan_rsp_data_2m[] = {
|
|
0x02, 0x01, 0x06,
|
|
0x02, 0x0a, 0xeb,
|
|
0x11, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A',
|
|
'D', 'V', '_', '2', 'M'
|
|
};
|
|
|
|
static uint8_t legacy_adv_data[] = {
|
|
0x02, 0x01, 0x06,
|
|
0x02, 0x0a, 0xeb,
|
|
0x14, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A',
|
|
'D', 'V', '_', 'C', 'O', 'D', 'E', 'D'
|
|
};
|
|
|
|
static uint8_t legacy_scan_rsp_data[] = {
|
|
0x02, 0x01, 0x06,
|
|
0x02, 0x0a, 0xeb,
|
|
0x15, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A',
|
|
'D', 'V', '_', 'L', 'E', 'G', 'A', 'C', 'Y'
|
|
};
|
|
|
|
static uint8_t raw_scan_rsp_data_coded[] = {
|
|
0x02, 0x01, 0x06,
|
|
0x02, 0x0a, 0xeb,
|
|
0x14, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A',
|
|
'D', 'V', '_', 'C', 'O', 'D', 'E', 'D'
|
|
};
|
|
|
|
static esp_ble_gap_ext_adv_t ext_adv[4] = {
|
|
// instance, duration, peroid
|
|
[0] = {0, 0, 0},
|
|
[1] = {1, 0, 0},
|
|
[2] = {2, 0, 0},
|
|
[3] = {3, 0, 0},
|
|
};
|
|
|
|
static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
|
|
{
|
|
switch (event) {
|
|
case ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT:
|
|
xSemaphoreGive(test_sem);
|
|
ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, status %d", param->ext_adv_set_rand_addr.status);
|
|
break;
|
|
case ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT:
|
|
xSemaphoreGive(test_sem);
|
|
ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status %d", param->ext_adv_set_params.status);
|
|
break;
|
|
case ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT:
|
|
xSemaphoreGive(test_sem);
|
|
ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT, status %d", param->ext_adv_data_set.status);
|
|
break;
|
|
case ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT:
|
|
xSemaphoreGive(test_sem);
|
|
ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, status %d", param->scan_rsp_set.status);
|
|
break;
|
|
case ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT:
|
|
xSemaphoreGive(test_sem);
|
|
ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT, status %d", param->ext_adv_start.status);
|
|
break;
|
|
case ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT:
|
|
xSemaphoreGive(test_sem);
|
|
ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT, status %d", param->ext_adv_stop.status);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void app_main(void)
|
|
{
|
|
esp_err_t ret;
|
|
|
|
// Initialize NVS.
|
|
ret = nvs_flash_init();
|
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
|
ret = nvs_flash_init();
|
|
}
|
|
ESP_ERROR_CHECK( ret );
|
|
|
|
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();
|
|
ret = esp_bt_controller_init(&bt_cfg);
|
|
if (ret) {
|
|
ESP_LOGE(LOG_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret));
|
|
return;
|
|
}
|
|
|
|
ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
|
|
if (ret) {
|
|
ESP_LOGE(LOG_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret));
|
|
return;
|
|
}
|
|
ret = esp_bluedroid_init();
|
|
if (ret) {
|
|
ESP_LOGE(LOG_TAG, "%s init bluetooth failed: %s\n", __func__, esp_err_to_name(ret));
|
|
return;
|
|
}
|
|
ret = esp_bluedroid_enable();
|
|
if (ret) {
|
|
ESP_LOGE(LOG_TAG, "%s enable bluetooth failed: %s\n", __func__, esp_err_to_name(ret));
|
|
return;
|
|
}
|
|
ret = esp_ble_gap_register_callback(gap_event_handler);
|
|
if (ret){
|
|
ESP_LOGE(LOG_TAG, "gap register error, error code = %x", ret);
|
|
return;
|
|
}
|
|
|
|
vTaskDelay(200 / portTICK_PERIOD_MS);
|
|
|
|
test_sem = xSemaphoreCreateBinary();
|
|
// 1M phy extend adv, Connectable advertising
|
|
FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_params(0, &ext_adv_params_1M), test_sem);
|
|
FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_rand_addr(0, addr_1m), test_sem);
|
|
FUNC_SEND_WAIT_SEM(esp_ble_gap_config_ext_adv_data_raw(0, sizeof(raw_adv_data_1m), &raw_adv_data_1m[0]), test_sem);
|
|
|
|
// 2M phy extend adv, Scannable advertising
|
|
FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_params(1, &ext_adv_params_2M), test_sem);
|
|
FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_rand_addr(1, addr_2m), test_sem);
|
|
FUNC_SEND_WAIT_SEM(esp_ble_gap_config_ext_scan_rsp_data_raw(1, sizeof(raw_scan_rsp_data_2m), raw_scan_rsp_data_2m), test_sem);
|
|
|
|
// 1M phy legacy adv, ADV_IND
|
|
FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_params(2, &legacy_adv_params), test_sem);
|
|
FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_rand_addr(2, addr_legacy), test_sem);
|
|
FUNC_SEND_WAIT_SEM(esp_ble_gap_config_ext_adv_data_raw(2, sizeof(legacy_adv_data), &legacy_adv_data[0]), test_sem);
|
|
FUNC_SEND_WAIT_SEM(esp_ble_gap_config_ext_scan_rsp_data_raw(2, sizeof(legacy_scan_rsp_data), &legacy_scan_rsp_data[0]), test_sem);
|
|
|
|
// coded phy extend adv, Connectable advertising
|
|
FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_params(3, &ext_adv_params_coded), test_sem);
|
|
FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_rand_addr(3, addr_coded), test_sem);
|
|
FUNC_SEND_WAIT_SEM(esp_ble_gap_config_ext_scan_rsp_data_raw(3, sizeof(raw_scan_rsp_data_coded), &raw_scan_rsp_data_coded[0]), test_sem);
|
|
|
|
// start all adv
|
|
FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_start(4, &ext_adv[0]), test_sem);
|
|
|
|
return;
|
|
}
|