Page 1 of 1

使用 coded PHY 来做 Advertising 的问题

Posted: Tue Jan 17, 2023 11:36 am
by KarrDong
我要使用 ESP32-C3 来做一个 BLE Long Range 广播封包,我使用 multi_adv_demo.c 来修改,程序档案如下,
  1.  
  2. #define FUNC_SEND_WAIT_SEM(func, sem) do {\
  3.         esp_err_t __err_rc = (func);\
  4.         if (__err_rc != ESP_OK) { \
  5.             ESP_LOGE(LOG_TAG, "%s, message send fail, error = %d", __func__, __err_rc); \
  6.         } \
  7.         xSemaphoreTake(sem, portMAX_DELAY); \
  8. } while(0);
  9.  
  10. static SemaphoreHandle_t test_sem = NULL;
  11.  
  12. esp_ble_gap_ext_adv_params_t legacy_adv_params = {
  13.     .type = ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_IND,
  14.     .interval_min = 320,
  15.     .interval_max = 640,
  16.     .channel_map = ADV_CHNL_ALL,
  17.     .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
  18.     .primary_phy = ESP_BLE_GAP_PHY_1M,
  19.     .max_skip = 0,
  20.     .secondary_phy = ESP_BLE_GAP_PHY_1M,
  21.     .sid = 0,
  22.     .scan_req_notif = false,
  23.     .own_addr_type = BLE_ADDR_TYPE_PUBLIC,
  24. };
  25.  
  26. esp_ble_gap_ext_adv_params_t ext_adv_params_coded = {
  27.     .type = ESP_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE,
  28.     .interval_min = 640,
  29.     .interval_max = 960,
  30.     .channel_map = ADV_CHNL_ALL,
  31.     .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
  32.     .primary_phy = ESP_BLE_GAP_PHY_CODED,
  33.     .max_skip = 0,
  34.     .secondary_phy = ESP_BLE_GAP_PHY_CODED,
  35.     .sid = 1,
  36.     .scan_req_notif = false,
  37.     .own_addr_type = BLE_ADDR_TYPE_PUBLIC,
  38. };
  39.  
  40. static uint8_t legacy_adv_data[] = {
  41.         0x02, 0x01, 0x06,
  42.         0x02, 0x0a, 0xeb,
  43.         0x14, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A',
  44.         'D', 'V', '_', 'C', 'O', 'D', 'E', 'D'
  45. };
  46.  
  47. static uint8_t legacy_scan_rsp_data[] = {
  48.         0x02, 0x01, 0x06,
  49.         0x02, 0x0a, 0xeb,
  50.         0x15, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A',
  51.         'D', 'V', '_', 'L', 'E', 'G', 'A', 'C', 'Y'
  52. };
  53.  
  54. static uint8_t raw_scan_rsp_data_coded[] = {
  55.         0x02, 0x01, 0x06,
  56.         0x02, 0x0a, 0xeb,
  57.         0x14, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A',
  58.         'D', 'V', '_', 'C', 'O', 'D', 'E', 'D'
  59. };
  60.  
  61. static esp_ble_gap_ext_adv_t ext_adv[4] = {
  62.     // instance, duration, peroid
  63.     [0] = {0, 0, 0},
  64.     [1] = {1, 0, 0},
  65. };
  66.  
  67. static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
  68. {
  69.     switch (event) {
  70.     case ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT:
  71.         xSemaphoreGive(test_sem);
  72.         ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, status %d", param->ext_adv_set_rand_addr.status);
  73.         break;
  74.     case ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT:
  75.         xSemaphoreGive(test_sem);
  76.         ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status %d", param->ext_adv_set_params.status);
  77.         break;
  78.     case ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT:
  79.         xSemaphoreGive(test_sem);
  80.         ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT, status %d", param->ext_adv_data_set.status);
  81.         break;
  82.     case ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT:
  83.         xSemaphoreGive(test_sem);
  84.         ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, status %d", param->scan_rsp_set.status);
  85.         break;
  86.     case ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT:
  87.         xSemaphoreGive(test_sem);
  88.         ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT, status %d", param->ext_adv_start.status);
  89.         break;
  90.     case ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT:
  91.         xSemaphoreGive(test_sem);
  92.         ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT, status %d", param->ext_adv_stop.status);
  93.         break;
  94.     default:
  95.         break;
  96.     }
  97. }
  98.  
  99. void app_main(void)
  100. {
  101.     esp_err_t ret;
  102.  
  103.     // Initialize NVS.
  104.     ret = nvs_flash_init();
  105.     if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
  106.         ESP_ERROR_CHECK(nvs_flash_erase());
  107.         ret = nvs_flash_init();
  108.     }
  109.     ESP_ERROR_CHECK( ret );
  110.  
  111.     ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
  112.  
  113.     esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
  114.     ret = esp_bt_controller_init(&bt_cfg);
  115.     if (ret) {
  116.         ESP_LOGE(LOG_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret));
  117.         return;
  118.     }
  119.  
  120.     ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
  121.     if (ret) {
  122.         ESP_LOGE(LOG_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret));
  123.         return;
  124.     }
  125.     ret = esp_bluedroid_init();
  126.     if (ret) {
  127.         ESP_LOGE(LOG_TAG, "%s init bluetooth failed: %s\n", __func__, esp_err_to_name(ret));
  128.         return;
  129.     }
  130.     ret = esp_bluedroid_enable();
  131.     if (ret) {
  132.         ESP_LOGE(LOG_TAG, "%s enable bluetooth failed: %s\n", __func__, esp_err_to_name(ret));
  133.         return;
  134.     }
  135.     ret = esp_ble_gap_register_callback(gap_event_handler);
  136.     if (ret){
  137.         ESP_LOGE(LOG_TAG, "gap register error, error code = %x", ret);
  138.         return;
  139.     }
  140.  
  141.     vTaskDelay(200 / portTICK_PERIOD_MS);
  142.  
  143.     test_sem = xSemaphoreCreateBinary();
  144.  
  145.     // 1M phy legacy adv, ADV_IND
  146.     FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_params(0, &legacy_adv_params), test_sem);
  147.     FUNC_SEND_WAIT_SEM(esp_ble_gap_config_ext_adv_data_raw(0, sizeof(legacy_adv_data), &legacy_adv_data[0]), test_sem);
  148.     FUNC_SEND_WAIT_SEM(esp_ble_gap_config_ext_scan_rsp_data_raw(0, sizeof(legacy_scan_rsp_data), &legacy_scan_rsp_data[0]), test_sem);
  149.  
  150.     // coded phy extend adv, Connectable advertising
  151.     FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_params(1, &ext_adv_params_coded), test_sem);
  152. //    FUNC_SEND_WAIT_SEM(esp_ble_gap_config_ext_adv_data_raw(1, sizeof(legacy_adv_data), &legacy_adv_data[0]), test_sem);
  153.     FUNC_SEND_WAIT_SEM(esp_ble_gap_config_ext_scan_rsp_data_raw(1, sizeof(raw_scan_rsp_data_coded), &raw_scan_rsp_data_coded[0]), test_sem);
  154.  
  155.     // start all adv
  156.     FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_start(2, &ext_adv[0]), test_sem);
  157.  
  158.     return;
  159. }
执行时 log 显示程序正确执行,我也于 Sniffer 上看见了 Long Range 格式的 SCAN RSP 封包。

I (641) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status 0
I (641) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT, status 0
I (641) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, status 0
I (651) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status 0
I (661) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, status 0
I (671) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT, status 0

我现在想要将 Long Range 广播封包改成 ADV 封包,但于
FUNC_SEND_WAIT_SEM(esp_ble_gap_config_ext_adv_data_raw(1, sizeof(legacy_adv_data), &legacy_adv_data[0]), test_sem);

却出现了问题,LOG 如下

I (641) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status 0
I (641) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT, status 0
I (641) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, status 0
I (651) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status 0
E (661) BT_BTM: LE EA SetAdvData: cmd err=0x12
I (661) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT, status 7
I (671) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, status 0
I (681) MULTI_ADV_DEMO: ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT, status 0

请问我该如何修改呢?