mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-31 13:09:38 +00:00 
			
		
		
		
	Merge branch 'bugfix/Fix_ios_ble_adv_rsp_v4.3' into 'release/v4.3'
Fix iOS advertisement response and simplify (v4.3) See merge request espressif/esp-idf!18039
This commit is contained in:
		| @@ -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) | static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) | ||||||
| { | { | ||||||
|     switch (event) { |     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); |         adv_config_done &= (~adv_config_flag); | ||||||
|         if (adv_config_done == 0) { |         if (adv_config_done == 0) { | ||||||
|             esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params); |             esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params); | ||||||
|         } |         } | ||||||
|         break; |         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); |         adv_config_done &= (~scan_rsp_config_flag); | ||||||
|         if (adv_config_done == 0) { |         if (adv_config_done == 0) { | ||||||
|             esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params); |             esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params); | ||||||
| @@ -91,15 +91,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); |             ESP_LOGE(TAG, "set device name failed, error code = 0x%x", ret); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         ret = esp_ble_gap_config_adv_data_raw(g_ble_cfg_p->raw_adv_data_p, |         ret = esp_ble_gap_config_adv_data(g_ble_cfg_p->adv_data_p); | ||||||
|                                               g_ble_cfg_p->raw_adv_data_len); |  | ||||||
|         if (ret) { |         if (ret) { | ||||||
|             ESP_LOGE(TAG, "config raw adv data failed, error code = 0x%x ", ret); |             ESP_LOGE(TAG, "config raw adv data failed, error code = 0x%x ", ret); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         adv_config_done |= adv_config_flag; |         adv_config_done |= adv_config_flag; | ||||||
|         ret = esp_ble_gap_config_scan_rsp_data_raw(g_ble_cfg_p->raw_scan_rsp_data_p, |         ret = esp_ble_gap_config_adv_data(g_ble_cfg_p->scan_rsp_data_p); | ||||||
|                                                    g_ble_cfg_p->raw_scan_rsp_data_len); |  | ||||||
|         if (ret) { |         if (ret) { | ||||||
|             ESP_LOGE(TAG, "config raw scan rsp data failed, error code = 0x%x", ret); |             ESP_LOGE(TAG, "config raw scan rsp data failed, error code = 0x%x", ret); | ||||||
|             return; |             return; | ||||||
|   | |||||||
| @@ -25,11 +25,9 @@ typedef struct { | |||||||
|     /** Name to be displayed to devices scanning for ESP32 */ |     /** Name to be displayed to devices scanning for ESP32 */ | ||||||
|     const char *device_name; |     const char *device_name; | ||||||
|     /** Raw advertisement data */ |     /** Raw advertisement data */ | ||||||
|     uint8_t *raw_adv_data_p; |     esp_ble_adv_data_t *adv_data_p; | ||||||
|     uint8_t raw_adv_data_len; |  | ||||||
|     /** Raw scan response data */ |     /** Raw scan response data */ | ||||||
|     uint8_t *raw_scan_rsp_data_p; |     esp_ble_adv_data_t *scan_rsp_data_p; | ||||||
|     uint8_t raw_scan_rsp_data_len; |  | ||||||
|     /** Parameters to configure the nature of advertising */ |     /** Parameters to configure the nature of advertising */ | ||||||
|     esp_ble_adv_params_t adv_params; |     esp_ble_adv_params_t adv_params; | ||||||
|     /** Descriptor table which consists of the configuration |     /** Descriptor table which consists of the configuration | ||||||
|   | |||||||
| @@ -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_declaration_uuid = ESP_GATT_UUID_CHAR_DECLARE; | ||||||
| static const uint16_t character_user_description = ESP_GATT_UUID_CHAR_DESCRIPTION; | 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  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 { | typedef struct { | ||||||
|     uint8_t type; |     uint8_t type; | ||||||
| @@ -52,14 +51,33 @@ typedef struct _protocomm_ble { | |||||||
|     ssize_t g_nu_lookup_count; |     ssize_t g_nu_lookup_count; | ||||||
|     uint16_t gatt_mtu; |     uint16_t gatt_mtu; | ||||||
|     uint8_t *service_uuid; |     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; | } _protocomm_ble_internal_t; | ||||||
|  |  | ||||||
| static _protocomm_ble_internal_t *protoble_internal; | 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 = { | static esp_ble_adv_params_t adv_params = { | ||||||
|     .adv_int_min         = 0x100, |     .adv_int_min         = 0x100, | ||||||
|     .adv_int_max         = 0x100, |     .adv_int_max         = 0x100, | ||||||
| @@ -417,8 +435,6 @@ static void protocomm_ble_cleanup(void) | |||||||
|             } |             } | ||||||
|             free(protoble_internal->g_nu_lookup); |             free(protoble_internal->g_nu_lookup); | ||||||
|         } |         } | ||||||
|         free(protoble_internal->raw_adv_data_p); |  | ||||||
|         free(protoble_internal->raw_scan_rsp_data_p); |  | ||||||
|         free(protoble_internal); |         free(protoble_internal); | ||||||
|         protoble_internal = NULL; |         protoble_internal = NULL; | ||||||
|     } |     } | ||||||
| @@ -491,133 +507,14 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con | |||||||
|     protoble_internal->pc_ble = pc; |     protoble_internal->pc_ble = pc; | ||||||
|     protoble_internal->gatt_mtu = ESP_GATT_DEF_BLE_MTU_SIZE; |     protoble_internal->gatt_mtu = ESP_GATT_DEF_BLE_MTU_SIZE; | ||||||
|  |  | ||||||
|     /* The BLE advertisement data (max 31 bytes) consists of: |     // Config adv data | ||||||
|      * 1) Flags - |     adv_config.service_uuid_len = ESP_UUID_LEN_128; | ||||||
|      *      Size : length (1 byte) + type (1 byte) + value (1 byte) = 3 bytes |     adv_config.p_service_uuid = (uint8_t *) config->service_uuid; | ||||||
|      * 2) Complete 128 bit UUID of the service - |     protoble_internal->service_uuid = (uint8_t *) config->service_uuid; | ||||||
|      *      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 */ |     // Config scan response data | ||||||
|     uint8_t adv_data_len = 0; |     scan_rsp_config.manufacturer_len = protocomm_ble_mfg_data_len; | ||||||
|     for (uint8_t i = 0; i < (sizeof(adv_data) / sizeof(adv_data[0])); i++) { |     scan_rsp_config.p_manufacturer_data = (uint8_t *) protocomm_ble_mfg_data; | ||||||
|         /* 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) |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     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; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     simple_ble_cfg_t *ble_config = simple_ble_init(); |     simple_ble_cfg_t *ble_config = simple_ble_init(); | ||||||
|     if (ble_config == NULL) { |     if (ble_config == NULL) { | ||||||
| @@ -637,10 +534,8 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con | |||||||
|     /* Set parameters required for advertising */ |     /* Set parameters required for advertising */ | ||||||
|     ble_config->adv_params      = adv_params; |     ble_config->adv_params      = adv_params; | ||||||
|  |  | ||||||
|     ble_config->raw_adv_data_p        = protoble_internal->raw_adv_data_p; |     ble_config->adv_data_p      = &adv_config; | ||||||
|     ble_config->raw_adv_data_len      = protoble_internal->raw_adv_data_len; |     ble_config->scan_rsp_data_p = &scan_rsp_config; | ||||||
|     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->device_name     = protocomm_ble_device_name; |     ble_config->device_name     = protocomm_ble_device_name; | ||||||
|     ble_config->gatt_db_count   = populate_gatt_db(&ble_config->gatt_db); |     ble_config->gatt_db_count   = populate_gatt_db(&ble_config->gatt_db); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jiang Jiang Jian
					Jiang Jiang Jian