mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-31 04:59:55 +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) | ||||
| { | ||||
|     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); | ||||
| @@ -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); | ||||
|             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; | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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, | ||||
| @@ -417,8 +435,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; | ||||
|     } | ||||
| @@ -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->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 | ||||
|         }, | ||||
|     }; | ||||
|     // 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; | ||||
|  | ||||
|     /* 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) | ||||
|      */ | ||||
|  | ||||
|     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) { | ||||
| @@ -637,10 +534,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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jiang Jiang Jian
					Jiang Jiang Jian