Selaa lähdekoodia

Fix iOS advertisement response and simplify

lorenzo.consolaro 3 vuotta sitten
vanhempi
sitoutus
87cc13f369

+ 4 - 6
components/protocomm/src/simple_ble/simple_ble.c

@@ -42,13 +42,13 @@ const uint8_t *simple_ble_get_uuid128(uint16_t handle)
 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_ADV_DATA_RAW_SET_COMPLETE_EVT:
+    case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
         adv_config_done &= (~adv_config_flag);
         if (adv_config_done == 0) {
             esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params);
         }
         break;
-    case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT:
+    case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
         adv_config_done &= (~scan_rsp_config_flag);
         if (adv_config_done == 0) {
             esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params);
@@ -94,15 +94,13 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_
             ESP_LOGE(TAG, "set device name failed, error code = 0x%x", ret);
             return;
         }
-        ret = esp_ble_gap_config_adv_data_raw(g_ble_cfg_p->raw_adv_data_p,
-                                              g_ble_cfg_p->raw_adv_data_len);
+        ret = esp_ble_gap_config_adv_data(g_ble_cfg_p->adv_data_p);
         if (ret) {
             ESP_LOGE(TAG, "config raw adv data failed, error code = 0x%x ", ret);
             return;
         }
         adv_config_done |= adv_config_flag;
-        ret = esp_ble_gap_config_scan_rsp_data_raw(g_ble_cfg_p->raw_scan_rsp_data_p,
-                                                   g_ble_cfg_p->raw_scan_rsp_data_len);
+        ret = esp_ble_gap_config_adv_data(g_ble_cfg_p->scan_rsp_data_p);
         if (ret) {
             ESP_LOGE(TAG, "config raw scan rsp data failed, error code = 0x%x", ret);
             return;

+ 2 - 4
components/protocomm/src/simple_ble/simple_ble.h

@@ -25,11 +25,9 @@ typedef struct {
     /** Name to be displayed to devices scanning for ESP32 */
     const char *device_name;
     /** Raw advertisement data */
-    uint8_t *raw_adv_data_p;
-    uint8_t raw_adv_data_len;
+    esp_ble_adv_data_t *adv_data_p;
     /** Raw scan response data */
-    uint8_t *raw_scan_rsp_data_p;
-    uint8_t raw_scan_rsp_data_len;
+    esp_ble_adv_data_t *scan_rsp_data_p;
     /** Parameters to configure the nature of advertising */
     esp_ble_adv_params_t adv_params;
     /** Descriptor table which consists of the configuration

+ 32 - 137
components/protocomm/src/transports/protocomm_ble.c

@@ -25,7 +25,6 @@ static const uint16_t primary_service_uuid       = ESP_GATT_UUID_PRI_SERVICE;
 static const uint16_t character_declaration_uuid = ESP_GATT_UUID_CHAR_DECLARE;
 static const uint16_t character_user_description = ESP_GATT_UUID_CHAR_DESCRIPTION;
 static const uint8_t  character_prop_read_write  = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE;
-static const uint8_t  ble_advertisement_flags    = ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT;
 
 typedef struct {
     uint8_t type;
@@ -52,14 +51,33 @@ typedef struct _protocomm_ble {
     ssize_t g_nu_lookup_count;
     uint16_t gatt_mtu;
     uint8_t *service_uuid;
-    uint8_t *raw_adv_data_p;
-    uint8_t raw_adv_data_len;
-    uint8_t *raw_scan_rsp_data_p;
-    uint8_t raw_scan_rsp_data_len;
 } _protocomm_ble_internal_t;
 
 static _protocomm_ble_internal_t *protoble_internal;
 
+// config adv data
+static esp_ble_adv_data_t adv_config = {
+    .set_scan_rsp = false,
+    .include_txpower = true,
+    .min_interval = 0x0006, //slave connection min interval, Time = min_interval * 1.25 msec
+    .max_interval = 0x0010, //slave connection max interval, Time = max_interval * 1.25 msec
+    .appearance = 0x00,
+    .manufacturer_len = 0,
+    .p_manufacturer_data =  NULL,
+    .service_data_len = 0,
+    .p_service_data = NULL,
+    .service_uuid_len = 0,  // Filled later
+    .p_service_uuid = NULL, // Filled later
+    .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
+};
+// config scan response data
+static esp_ble_adv_data_t scan_rsp_config = {
+    .set_scan_rsp = true,
+    .include_name = true,
+    .manufacturer_len = 0,          // Filled later
+    .p_manufacturer_data = NULL,    // Filler later
+};
+
 static esp_ble_adv_params_t adv_params = {
     .adv_int_min         = 0x100,
     .adv_int_max         = 0x100,
@@ -418,8 +436,6 @@ static void protocomm_ble_cleanup(void)
             }
             free(protoble_internal->g_nu_lookup);
         }
-        free(protoble_internal->raw_adv_data_p);
-        free(protoble_internal->raw_scan_rsp_data_p);
         free(protoble_internal);
         protoble_internal = NULL;
     }
@@ -492,133 +508,14 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con
     protoble_internal->pc_ble = pc;
     protoble_internal->gatt_mtu = ESP_GATT_DEF_BLE_MTU_SIZE;
 
-    /* The BLE advertisement data (max 31 bytes) consists of:
-     * 1) Flags -
-     *      Size : length (1 byte) + type (1 byte) + value (1 byte) = 3 bytes
-     * 2) Complete 128 bit UUID of the service -
-     *      Size : length (1 byte) + type (1 byte) + value (16 bytes) = 18 bytes
-     *
-     * Remaining 31 - (3 + 18) = 10 bytes could be used for manufacturer data
-     * or something else in the future.
-     */
-    raw_data_info_t adv_data[] = {
-        {   /* Flags */
-            .type   = ESP_BLE_AD_TYPE_FLAG,
-            .length = sizeof(ble_advertisement_flags),
-            .data_p = (uint8_t *) &ble_advertisement_flags
-        },
-        {   /* 128 bit Service UUID */
-            .type   = ESP_BLE_AD_TYPE_128SRV_CMPL,
-            .length = ESP_UUID_LEN_128,
-            .data_p = (uint8_t *) config->service_uuid
-        },
-    };
-
-    /* Get the total raw data length required for above entries */
-    uint8_t adv_data_len = 0;
-    for (uint8_t i = 0; i < (sizeof(adv_data) / sizeof(adv_data[0])); i++) {
-        /* Add extra bytes required per entry, i.e.
-         * length (1 byte) + type (1 byte) = 2 bytes */
-        adv_data_len += adv_data[i].length + 2;
-    }
-    if (adv_data_len > ESP_BLE_ADV_DATA_LEN_MAX) {
-        ESP_LOGE(TAG, "Advertisement data too long = %d bytes", adv_data_len);
-        protocomm_ble_cleanup();
-        return ESP_ERR_NO_MEM;
-    }
-
-    /* Allocate memory for the raw advertisement data */
-    protoble_internal->raw_adv_data_len = adv_data_len;
-    protoble_internal->raw_adv_data_p = malloc(adv_data_len);
-    if (protoble_internal->raw_adv_data_p == NULL) {
-        ESP_LOGE(TAG, "Error allocating memory for raw advertisement data");
-        protocomm_ble_cleanup();
-        return ESP_ERR_NO_MEM;
-    }
-
-    /* Form the raw advertisement data using above entries */
-    for (uint8_t i = 0, len = 0; i < (sizeof(adv_data) / sizeof(adv_data[0])); i++) {
-        protoble_internal->raw_adv_data_p[len++] = adv_data[i].length + 1; // + 1 byte for type
-        protoble_internal->raw_adv_data_p[len++] = adv_data[i].type;
-        memcpy(&protoble_internal->raw_adv_data_p[len],
-               adv_data[i].data_p, adv_data[i].length);
-
-        if (adv_data[i].type == ESP_BLE_AD_TYPE_128SRV_CMPL) {
-            /* Remember where the primary service UUID is kept in the
-             * raw advertisement data, so that it can be used while
-             * populating the GATT database
-             */
-            protoble_internal->service_uuid = &protoble_internal->raw_adv_data_p[len];
-        }
-
-        len += adv_data[i].length;
-    }
-
-    size_t ble_devname_len = strlen(protocomm_ble_device_name);
-    /* The BLE scan response (31 bytes) consists of:
-     * 1) Device name (complete / incomplete) -
-     *      Size : The maximum supported name length
-     *              will be 31 - 2 (length + type) = 29 bytes
-     *
-     * Any remaining space may be used for accommodating
-     * other fields in the future
-     *
-     * 2) Manufacturer Data (To be truncated depending upon available size)
-     *      Size : The maximum supported manufacturer data size
-     *              will be 31 - 2 (length + type) - ble_devname_len - 2 (length + type)
-     */
+    // Config adv data
+    adv_config.service_uuid_len = ESP_UUID_LEN_128;
+    adv_config.p_service_uuid = (uint8_t *) config->service_uuid;
+    protoble_internal->service_uuid = (uint8_t *) config->service_uuid;
 
-    raw_data_info_t scan_resp_data[] = {
-        {   /* If full device name can fit in the scan response then indicate
-             * that by setting type to "Complete Name", else set it to "Short Name"
-             * so that client can fetch full device name - after connecting - by
-             * reading the device name characteristic under GAP service */
-            .type   = (ble_devname_len > (ESP_BLE_SCAN_RSP_DATA_LEN_MAX - 2) ?
-                       ESP_BLE_AD_TYPE_NAME_SHORT : ESP_BLE_AD_TYPE_NAME_CMPL),
-            .length = MIN(ble_devname_len, (ESP_BLE_SCAN_RSP_DATA_LEN_MAX - 2)),
-            .data_p = (uint8_t *) protocomm_ble_device_name
-        },
-        {
-            0,
-        },
-    };
-
-    if (protocomm_ble_mfg_data_len > 0) {
-        scan_resp_data[1].type = ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE;
-        scan_resp_data[1].length = protocomm_ble_mfg_data_len;
-        scan_resp_data[1].data_p = (uint8_t *) protocomm_ble_mfg_data;
-    }
-
-    /* Get the total raw scan response data length required for above entries */
-    uint8_t scan_resp_data_len = 0;
-    for (int i = 0; i < (sizeof(scan_resp_data) / sizeof(scan_resp_data[0])); i++) {
-        /* Add extra bytes required per entry, i.e.
-         * length (1 byte) + type (1 byte) = 2 bytes */
-        scan_resp_data_len += scan_resp_data[i].length + 2;
-    }
-    if (scan_resp_data_len > ESP_BLE_SCAN_RSP_DATA_LEN_MAX) {
-        ESP_LOGE(TAG, "Scan response data too long = %d bytes", scan_resp_data_len);
-        protocomm_ble_cleanup();
-        return ESP_ERR_NO_MEM;
-    }
-
-    /* Allocate memory for the raw scan response data */
-    protoble_internal->raw_scan_rsp_data_len = scan_resp_data_len;
-    protoble_internal->raw_scan_rsp_data_p = malloc(scan_resp_data_len);
-    if (protoble_internal->raw_scan_rsp_data_p == NULL) {
-        ESP_LOGE(TAG, "Error allocating memory for raw response data");
-        protocomm_ble_cleanup();
-        return ESP_ERR_NO_MEM;
-    }
-
-    /* Form the raw scan response data using above entries */
-    for (uint8_t i = 0, len = 0; i < (sizeof(scan_resp_data) / sizeof(scan_resp_data[0])); i++) {
-        protoble_internal->raw_scan_rsp_data_p[len++] = scan_resp_data[i].length + 1; // + 1 byte for type
-        protoble_internal->raw_scan_rsp_data_p[len++] = scan_resp_data[i].type;
-        memcpy(&protoble_internal->raw_scan_rsp_data_p[len],
-               scan_resp_data[i].data_p, scan_resp_data[i].length);
-        len += scan_resp_data[i].length;
-    }
+    // Config scan response data
+    scan_rsp_config.manufacturer_len = protocomm_ble_mfg_data_len;
+    scan_rsp_config.p_manufacturer_data = (uint8_t *) protocomm_ble_mfg_data;
 
     simple_ble_cfg_t *ble_config = simple_ble_init();
     if (ble_config == NULL) {
@@ -638,10 +535,8 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con
     /* Set parameters required for advertising */
     ble_config->adv_params      = adv_params;
 
-    ble_config->raw_adv_data_p        = protoble_internal->raw_adv_data_p;
-    ble_config->raw_adv_data_len      = protoble_internal->raw_adv_data_len;
-    ble_config->raw_scan_rsp_data_p   = protoble_internal->raw_scan_rsp_data_p;
-    ble_config->raw_scan_rsp_data_len = protoble_internal->raw_scan_rsp_data_len;
+    ble_config->adv_data_p      = &adv_config;
+    ble_config->scan_rsp_data_p = &scan_rsp_config;
 
     ble_config->device_name     = protocomm_ble_device_name;
     ble_config->gatt_db_count   = populate_gatt_db(&ble_config->gatt_db);