diff --git a/components/bt/common/btc/core/btc_task.c b/components/bt/common/btc/core/btc_task.c index 9bfd6fa8f27..580504b8466 100644 --- a/components/bt/common/btc/core/btc_task.c +++ b/components/bt/common/btc/core/btc_task.c @@ -225,8 +225,8 @@ static bt_status_t btc_task_post(btc_msg_t *msg, uint32_t timeout) /** * transfer an message to another module in the different task. * @param msg message - * @param arg paramter - * @param arg_len length of paramter + * @param arg parameter + * @param arg_len length of parameter * @param copy_func deep copy function * @param free_func deep free function * @return BT_STATUS_SUCCESS: success @@ -272,7 +272,7 @@ bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg } /** - * transfer an message to another module in tha same task. + * transfer an message to another module in the same task. * @param msg message * @return BT_STATUS_SUCCESS: success * others: fail diff --git a/components/bt/host/bluedroid/api/esp_sdp_api.c b/components/bt/host/bluedroid/api/esp_sdp_api.c index c47c5ba50a8..11e0e153406 100644 --- a/components/bt/host/bluedroid/api/esp_sdp_api.c +++ b/components/bt/host/bluedroid/api/esp_sdp_api.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,24 @@ #if (defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE) +static bool esp_sdp_record_integrity_check(esp_bluetooth_sdp_record_t *record) +{ + bool ret = true; + + if (record != NULL) { + if (record->hdr.service_name_length > ESP_SDP_SERVER_NAME_MAX || + strlen(record->hdr.service_name) + 1 != record->hdr.service_name_length) { + LOG_ERROR("Invalid server name!\n"); + ret = false; + } + } else { + LOG_ERROR("record is NULL!\n"); + ret = false; + } + + return ret; +} + esp_err_t esp_sdp_register_callback(esp_sdp_cb_t callback) { ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); @@ -85,9 +103,7 @@ esp_err_t esp_sdp_create_record(esp_bluetooth_sdp_record_t *record) { ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); - if (record == NULL || record->hdr.service_name_length > ESP_SDP_SERVER_NAME_MAX - || strlen(record->hdr.service_name)+1 != record->hdr.service_name_length) { - LOG_ERROR("Invalid server name!\n"); + if (!esp_sdp_record_integrity_check(record)) { return ESP_ERR_INVALID_ARG; } @@ -100,7 +116,7 @@ esp_err_t esp_sdp_create_record(esp_bluetooth_sdp_record_t *record) msg.act = BTC_SDP_ACT_CREATE_RECORD; memset(&arg, 0, sizeof(btc_sdp_args_t)); - arg.creat_record.record = (bluetooth_sdp_record *)record; + arg.create_record.record = (bluetooth_sdp_record *)record; /* Switch to BTC context */ stat = btc_transfer_context(&msg, &arg, sizeof(btc_sdp_args_t), diff --git a/components/bt/host/bluedroid/api/include/api/esp_sdp_api.h b/components/bt/host/bluedroid/api/include/api/esp_sdp_api.h index 14741e74714..50c79b8ba17 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_sdp_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_sdp_api.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,123 +14,131 @@ extern "C" { #endif -#define ESP_SDP_SERVER_NAME_MAX 32 /*!< Service name max length */ -#define SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH 15 /*!< OPP supported format list maximum length */ +#define ESP_SDP_SERVER_NAME_MAX 32 /*!< Service name max length */ +#define SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH 15 /*!< OPP supported format list maximum length */ + +#define ESP_SDP_UUID_MAP_MAS 0x1132 /*!< Message Access Service UUID */ +#define ESP_SDP_UUID_MAP_MNS 0x1133 /*!< Message Notification Service UUID */ +#define ESP_SDP_UUID_PBAP_PSE 0x112F /*!< Phone Book Server Equipment UUID */ +#define ESP_SDP_UUID_PBAP_PCE 0x112E /*!< Phone Book Client Equipment UUID */ +#define ESP_SDP_UUID_OPP 0x1105 /*!< Object Push Profile UUID */ +#define ESP_SDP_UUID_SAP 0x112D /*!< SIM Access Profile UUID */ +#define ESP_SDP_UUID_DIP 0x1200 /*!< Device Identification Profile UUID */ + +#define ESP_SDP_BUILD_BT_UUID16(uuid16_val) \ + (esp_bt_uuid_t) { .len = ESP_UUID_LEN_16, .uuid = {.uuid16 = (uint16_t)(uuid16_val),}, } typedef enum { - ESP_SDP_SUCCESS = 0, /*!< Successful operation. */ - ESP_SDP_FAILURE, /*!< Generic failure. */ - ESP_SDP_NO_RESOURCE, /*!< No more resource */ - ESP_SDP_NEED_INIT, /*!< SDP module shall init first */ - ESP_SDP_NEED_DEINIT, /*!< SDP module shall deinit first */ - ESP_SDP_NO_CREATE_RECORD, /*!< No record created */ + ESP_SDP_SUCCESS = 0, /*!< Successful operation. */ + ESP_SDP_FAILURE, /*!< Generic failure. */ + ESP_SDP_NO_RESOURCE, /*!< No more resource */ + ESP_SDP_NEED_INIT, /*!< SDP module shall init first */ + ESP_SDP_NEED_DEINIT, /*!< SDP module shall deinit first */ + ESP_SDP_NO_CREATE_RECORD, /*!< No record created */ } esp_sdp_status_t; /** * @brief SDP callback function events */ typedef enum { - ESP_SDP_INIT_EVT = 0, /*!< When SDP is initialized, the event comes */ - ESP_SDP_DEINIT_EVT = 1, /*!< When SDP is deinitialized, the event comes */ - ESP_SDP_SEARCH_COMP_EVT = 2, /*!< When SDP search complete, the event comes */ - ESP_SDP_CREATE_RECORD_COMP_EVT = 3, /*!< When create SDP records complete, the event comes */ - ESP_SDP_REMOVE_RECORD_COMP_EVT = 4, /*!< When remove a SDP record complete, the event comes */ + ESP_SDP_INIT_EVT = 0, /*!< When SDP is initialized, the event comes */ + ESP_SDP_DEINIT_EVT = 1, /*!< When SDP is de-initialized, the event comes */ + ESP_SDP_SEARCH_COMP_EVT = 2, /*!< When SDP search complete, the event comes */ + ESP_SDP_CREATE_RECORD_COMP_EVT = 3, /*!< When create SDP records complete, the event comes */ + ESP_SDP_REMOVE_RECORD_COMP_EVT = 4, /*!< When remove a SDP record complete, the event comes */ } esp_sdp_cb_event_t; /** * @brief SDP record type */ typedef enum { - ESP_SDP_TYPE_RAW, /*!< Used to carry raw SDP search data for unknown UUIDs */ - ESP_SDP_TYPE_MAP_MAS, /*!< Message Access Profile - Server */ - ESP_SDP_TYPE_MAP_MNS, /*!< Message Access Profile - Client (Notification Server) */ - ESP_SDP_TYPE_PBAP_PSE, /*!< Phone Book Profile - Server */ - ESP_SDP_TYPE_PBAP_PCE, /*!< Phone Book Profile - Client */ - ESP_SDP_TYPE_OPP_SERVER, /*!< Object Push Profile */ - ESP_SDP_TYPE_SAP_SERVER /*!< SIM Access Profile */ + ESP_SDP_TYPE_RAW, /*!< Used to carry raw SDP search data for unknown UUIDs */ + ESP_SDP_TYPE_MAP_MAS, /*!< Message Access Profile - Server */ + ESP_SDP_TYPE_MAP_MNS, /*!< Message Access Profile - Client (Notification Server) */ + ESP_SDP_TYPE_PBAP_PSE, /*!< Phone Book Profile - Server */ + ESP_SDP_TYPE_PBAP_PCE, /*!< Phone Book Profile - Client */ + ESP_SDP_TYPE_OPP_SERVER, /*!< Object Push Profile */ + ESP_SDP_TYPE_SAP_SERVER, /*!< SIM Access Profile */ } esp_bluetooth_sdp_types_t; /** - * @brief Some signals need additional pointers, hence we introduce a - * generic way to handle these pointers. + * @brief SDP header structure */ typedef struct bluetooth_sdp_hdr_overlay { - esp_bluetooth_sdp_types_t type; /*!< SDP type */ - esp_bt_uuid_t uuid; /*!< UUID type, include uuid and uuid length */ - uint32_t service_name_length; /*!< Service name length */ - char *service_name; /*!< service name */ - int32_t rfcomm_channel_number; /*!< rfcomm channel number, if not used set to -1*/ - int32_t l2cap_psm; /*!< l2cap psm, if not used set to -1 */ - int32_t profile_version; /*!< profile version */ - - // User pointers, only used for some signals - see esp_bluetooth_sdp_ops_record_t - int user1_ptr_len; /*!< see esp_bluetooth_sdp_ops_record_t */ - uint8_t *user1_ptr; /*!< see esp_bluetooth_sdp_ops_record_t */ - int user2_ptr_len; /*!< see esp_bluetooth_sdp_ops_record_t */ - uint8_t *user2_ptr; /*!< see esp_bluetooth_sdp_ops_record_t */ + esp_bluetooth_sdp_types_t type; /*!< SDP type */ + esp_bt_uuid_t uuid; /*!< UUID type, include uuid and uuid length, only needed to be set for RAW record creation */ + uint32_t service_name_length; /*!< Service name length */ + char *service_name; /*!< Service name */ + int32_t rfcomm_channel_number; /*!< RFCOMM channel number, if not used set to -1*/ + int32_t l2cap_psm; /*!< L2CAP psm, if not used set to -1 */ + int32_t profile_version; /*!< Profile version */ + int user1_ptr_len; /*!< User data1 length, only used for searching RAW record */ + uint8_t *user1_ptr; /*!< User data1 pointer to the raw SDP response data, only used for searching RAW record */ + int user2_ptr_len; /*!< User data2 length, only used for searching RAW record */ + uint8_t *user2_ptr; /*!< User data2 pointer, only used for searching RAW record */ } esp_bluetooth_sdp_hdr_overlay_t; /** * @brief Message Access Profile - Server parameters */ typedef struct bluetooth_sdp_mas_record { - esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ - uint32_t mas_instance_id; /*!< MAS Instance ID */ - uint32_t supported_features; /*!< Map supported features */ - uint32_t supported_message_types; /*!< Supported message types */ + esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ + uint32_t mas_instance_id; /*!< MAS Instance ID */ + uint32_t supported_features; /*!< Map supported features */ + uint32_t supported_message_types; /*!< Supported message types */ } esp_bluetooth_sdp_mas_record_t; /** * @brief Message Access Profile - Client (Notification Server) parameters */ typedef struct bluetooth_sdp_mns_record { - esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ - uint32_t supported_features; /*!< Supported features */ + esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ + uint32_t supported_features; /*!< Supported features */ } esp_bluetooth_sdp_mns_record_t; /** * @brief Phone Book Profile - Server parameters */ typedef struct bluetooth_sdp_pse_record { - esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ - uint32_t supported_features; /*!< Pbap Supported Features */ - uint32_t supported_repositories; /*!< Supported Repositories */ + esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ + uint32_t supported_features; /*!< PBAP Supported Features */ + uint32_t supported_repositories; /*!< Supported Repositories */ } esp_bluetooth_sdp_pse_record_t; /** * @brief Phone Book Profile - Client parameters */ typedef struct bluetooth_sdp_pce_record { - esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ + esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ } esp_bluetooth_sdp_pce_record_t; /** * @brief Object Push Profile parameters */ typedef struct bluetooth_sdp_ops_record { - esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ - int supported_formats_list_len; /*!< Supported formats list length */ - uint8_t supported_formats_list[SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH]; /*!< Supported formats list */ + esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ + int supported_formats_list_len; /*!< Supported formats list length */ + uint8_t supported_formats_list[SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH]; /*!< Supported formats list */ } esp_bluetooth_sdp_ops_record_t; /** * @brief SIM Access Profile parameters */ typedef struct bluetooth_sdp_sap_record { - esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ + esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ } esp_bluetooth_sdp_sap_record_t; /** * @brief SDP record parameters union */ typedef union { - esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ - esp_bluetooth_sdp_mas_record_t mas; /*!< Message Access Profile - Server */ - esp_bluetooth_sdp_mns_record_t mns; /*!< Message Access Profile - Client (Notification Server) */ - esp_bluetooth_sdp_pse_record_t pse; /*!< Phone Book Profile - Server */ - esp_bluetooth_sdp_pce_record_t pce; /*!< Phone Book Profile - Client */ - esp_bluetooth_sdp_ops_record_t ops; /*!< Object Push Profile */ - esp_bluetooth_sdp_sap_record_t sap; /*!< SIM Access Profile */ + esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ + esp_bluetooth_sdp_mas_record_t mas; /*!< Message Access Profile - Server */ + esp_bluetooth_sdp_mns_record_t mns; /*!< Message Access Profile - Client (Notification Server) */ + esp_bluetooth_sdp_pse_record_t pse; /*!< Phone Book Profile - Server */ + esp_bluetooth_sdp_pce_record_t pce; /*!< Phone Book Profile - Client */ + esp_bluetooth_sdp_ops_record_t ops; /*!< Object Push Profile */ + esp_bluetooth_sdp_sap_record_t sap; /*!< SIM Access Profile */ } esp_bluetooth_sdp_record_t; /** @@ -141,44 +149,43 @@ typedef union { * @brief ESP_SDP_INIT_EVT */ struct sdp_init_evt_param { - esp_sdp_status_t status; /*!< status */ - } init; /*!< SDP callback param of ESP_SDP_INIT_EVT */ + esp_sdp_status_t status; /*!< Status */ + } init; /*!< SDP callback param of ESP_SDP_INIT_EVT */ /** * @brief ESP_SDP_DEINIT_EVT */ struct sdp_deinit_evt_param { - esp_sdp_status_t status; /*!< status */ - } deinit; /*!< SDP callback param of ESP_SDP_DEINIT_EVT */ + esp_sdp_status_t status; /*!< Status */ + } deinit; /*!< SDP callback param of ESP_SDP_DEINIT_EVT */ /** * @brief ESP_SDP_SEARCH_COMP_EVT */ struct sdp_search_evt_param { - esp_sdp_status_t status; /*!< status */ - esp_bd_addr_t remote_addr; /*!< remote device address */ - esp_bt_uuid_t sdp_uuid; /*!< service uuid */ - int record_count; /*!< Number of SDP records */ - esp_bluetooth_sdp_record_t *records;/*!< SDP records */ - } search; /*!< SDP callback param of ESP_SDP_SEARCH_COMP_EVT */ + esp_sdp_status_t status; /*!< Status */ + esp_bd_addr_t remote_addr; /*!< Remote device address */ + esp_bt_uuid_t sdp_uuid; /*!< Service uuid */ + int record_count; /*!< Number of SDP records */ + esp_bluetooth_sdp_record_t *records; /*!< SDP records */ + } search; /*!< SDP callback param of ESP_SDP_SEARCH_COMP_EVT */ /** * @brief ESP_SDP_CREATE_RECORD_COMP_EVT */ - struct sdp_crate_record_evt_param { - esp_sdp_status_t status; /*!< status */ - int record_handle; /*!< SDP record handle */ - } create_record; /*!< SDP callback param of ESP_SDP_CREATE_RECORD_COMP_EVT */ + struct sdp_create_record_evt_param { + esp_sdp_status_t status; /*!< Status */ + int record_handle; /*!< SDP record handle */ + } create_record; /*!< SDP callback param of ESP_SDP_CREATE_RECORD_COMP_EVT */ /** * @brief ESP_SDP_REMOVE_RECORD_COMP_EVT */ struct sdp_remove_record_evt_param { - esp_sdp_status_t status; /*!< status */ - } remove_record; /*!< SDP callback param of ESP_SDP_REMOVE_RECORD_COMP_EVT */ - -} esp_sdp_cb_param_t; /*!< SDP callback parameter union type */ + esp_sdp_status_t status; /*!< Status */ + } remove_record; /*!< SDP callback param of ESP_SDP_REMOVE_RECORD_COMP_EVT */ +} esp_sdp_cb_param_t; /** * @brief SDP callback function type. diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 83082e4b467..ad86921eea6 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -29,6 +29,7 @@ #include "stack/btm_api.h" #include "btm_int.h" #include +#include #include "bta/utl.h" #include "osi/allocator.h" @@ -991,22 +992,67 @@ UINT16 BTA_DmGetConnectionState( BD_ADDR bd_addr ) tBTA_STATUS BTA_DmSetLocalDiRecord( tBTA_DI_RECORD *p_device_info, UINT32 *p_handle ) { - tBTA_STATUS status = BTA_FAILURE; + tBTA_STATUS status = BTA_FAILURE; if (bta_dm_di_cb.di_num < BTA_DI_NUM_MAX) { if (SDP_SetLocalDiRecord((tSDP_DI_RECORD *)p_device_info, p_handle) == SDP_SUCCESS) { if (!p_device_info->primary_record) { - bta_dm_di_cb.di_handle[bta_dm_di_cb.di_num] = *p_handle; - bta_dm_di_cb.di_num ++; + for (uint8_t i = 1; i < BTA_DI_NUM_MAX; i++) { + if (!bta_dm_di_cb.di_handle[i]) { + bta_dm_di_cb.di_handle[i] = *p_handle; + break; + } + } + bta_dm_di_cb.di_num++; + } else if (!bta_dm_di_cb.di_handle[0]) { + bta_dm_di_cb.di_handle[0] = *p_handle; + bta_dm_di_cb.di_num++; + } else { + assert(bta_dm_di_cb.di_handle[0] == (*p_handle)); } - bta_sys_add_uuid(UUID_SERVCLASS_PNP_INFORMATION); - status = BTA_SUCCESS; + if (!bta_dm_di_cb.uuid_added) { + bta_sys_add_uuid(UUID_SERVCLASS_PNP_INFORMATION); + bta_dm_di_cb.uuid_added = TRUE; + } + + status = BTA_SUCCESS; } } return status; } + +/******************************************************************************* +** +** Function BTA_DmRemoveLocalDiRecord +** +** Description This function removes a DI record from the local SDP database. +** +** Returns BTA_SUCCESS if record is removed successfully, otherwise error code. +** +*******************************************************************************/ +tBTA_STATUS BTA_DmRemoveLocalDiRecord(UINT32 handle) +{ + tBTA_STATUS status = BTA_FAILURE; + + for (uint8_t i = 0; i < BTA_DI_NUM_MAX; i++) { + if (bta_dm_di_cb.di_handle[i] == handle) { + if (SDP_DeleteRecord(handle)) { + bta_dm_di_cb.di_handle[i] = 0; + bta_dm_di_cb.di_num--; + status = BTA_SUCCESS; + break; + } + } + } + + if (bta_dm_di_cb.di_num == 0 && bta_dm_di_cb.uuid_added) { + bta_sys_remove_uuid(UUID_SERVCLASS_PNP_INFORMATION); + } + + return status; +} #endif ///SDP_INCLUDED == TRUE /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 35ac3c39127..4d81f3675af 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -1541,6 +1541,7 @@ typedef struct { #if (SDP_INCLUDED == TRUE) tSDP_DISCOVERY_DB *p_di_db; /* pointer to the DI discovery database */ #endif ///SDP_INCLUDED == TRUE + BOOLEAN uuid_added; UINT8 di_num; /* total local DI record number */ UINT32 di_handle[BTA_DI_NUM_MAX]; /* local DI record handle, the first one is primary record */ } tBTA_DM_DI_CB; diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 4238e7bf752..9b3c88fec10 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -2125,6 +2125,17 @@ extern UINT16 BTA_DmGetConnectionState( BD_ADDR bd_addr ); *******************************************************************************/ extern tBTA_STATUS BTA_DmSetLocalDiRecord( tBTA_DI_RECORD *p_device_info, UINT32 *p_handle ); + +/******************************************************************************* +** +** Function BTA_DmRemoveLocalDiRecord +** +** Description This function removes a DI record from the local SDP database. +** +** Returns BTA_SUCCESS if record is removed successfully, otherwise error code. +** +*******************************************************************************/ +extern tBTA_STATUS BTA_DmRemoveLocalDiRecord(UINT32 handle); #endif ///SDP_INCLUDED == TRUE /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_sdp_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_sdp_api.h index 62b5228a885..fadc8183f0c 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_sdp_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_sdp_api.h @@ -41,7 +41,7 @@ typedef UINT8 tBTA_SDP_STATUS; /* SDP I/F callback events */ /* events received by tBTA_SDP_DM_CBACK */ #define BTA_SDP_ENABLE_EVT 0 /* SDP service enabled */ -#define BTA_SDP_DISENABLE_EVT 1 /* SDP service disenabled */ +#define BTA_SDP_DISABLE_EVT 1 /* SDP service disenabled */ #define BTA_SDP_SEARCH_EVT 2 /* SDP search started */ #define BTA_SDP_SEARCH_COMP_EVT 3 /* SDP search complete */ #define BTA_SDP_CREATE_RECORD_USER_EVT 4 /* SDP create record complete */ @@ -67,10 +67,17 @@ typedef struct { int handle; } tBTA_SDP_CREATE_RECORD_USER; +/* data associated with BTA_SDP_REMOVE_RECORD_USER_EVT */ +typedef struct { + tBTA_SDP_STATUS status; + int handle; +} tBTA_SDP_REMOVE_RECORD_USER; + typedef union { tBTA_SDP_STATUS status; /* BTA_SDP_SEARCH_EVT */ tBTA_SDP_SEARCH_COMP sdp_search_comp; /* BTA_SDP_SEARCH_COMP_EVT */ tBTA_SDP_CREATE_RECORD_USER sdp_create_record; /* BTA_SDP_CREATE_RECORD_USER_EVT */ + tBTA_SDP_REMOVE_RECORD_USER sdp_remove_record; /* BTA_SDP_REMOVE_RECORD_USER_EVT */ } tBTA_SDP; /* SDP DM Interface callback */ @@ -78,9 +85,11 @@ typedef void (tBTA_SDP_DM_CBACK)(tBTA_SDP_EVT event, tBTA_SDP *p_data, void *use /* MCE configuration structure */ typedef struct { - UINT16 sdp_db_size; /* The size of p_sdp_db */ + UINT16 sdp_raw_size; /* The size of p_sdp_raw_data */ + UINT16 sdp_db_size; /* The size of p_sdp_db */ #if (SDP_INCLUDED == TRUE) - tSDP_DISCOVERY_DB *p_sdp_db; /* The data buffer to keep SDP database */ + UINT8 *p_sdp_raw_data; /* The data buffer to keep raw data */ + tSDP_DISCOVERY_DB *p_sdp_db; /* The data buffer to keep SDP database */ #endif ///SDP_INCLUDED == TRUE } tBTA_SDP_CFG; @@ -108,14 +117,28 @@ extern tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK *p_cback); ** ** Function BTA_SdpDisable ** -** Description Disable the SDP search I/F service. +** Description This function is used to request a callback to perform disable +** operation. The registered callback will be called with event +** BTA_SDP_DISABLE_EVT. +** +** Returns BTA_SDP_SUCCESS, if the request is being processed. +** BTA_SDP_FAILURE, otherwise. +** +*******************************************************************************/ +extern tBTA_SDP_STATUS BTA_SdpDisable(void); + +/******************************************************************************* +** +** Function BTA_SdpCleanup +** +** Description Cleanup the SDP search I/F service. ** Free buffer for SDP configuration structure. ** ** Returns BTA_SDP_SUCCESS if successful. ** BTA_SDP_FAIL if internal failure. ** *******************************************************************************/ -extern tBTA_SDP_STATUS BTA_SdpDisable(void); +extern tBTA_SDP_STATUS BTA_SdpCleanup(void); /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/sdp/bta_sdp.c b/components/bt/host/bluedroid/bta/sdp/bta_sdp.c index 4deabe9aff9..71773d984c6 100644 --- a/components/bt/host/bluedroid/bta/sdp/bta_sdp.c +++ b/components/bt/host/bluedroid/bta/sdp/bta_sdp.c @@ -49,10 +49,11 @@ typedef void (*tBTA_SDP_ACTION)(tBTA_SDP_MSG *p_data); /* action function list */ const tBTA_SDP_ACTION bta_sdp_action[] = { - bta_sdp_enable, /* BTA_SDP_API_ENABLE_EVT */ - bta_sdp_search, /* BTA_SDP_API_SEARCH_EVT */ - bta_sdp_create_record, /* BTA_SDP_API_CREATE_RECORD_USER_EVT */ - bta_sdp_remove_record, /* BTA_SDP_API_REMOVE_RECORD_USER_EVT */ + bta_sdp_enable, /* BTA_SDP_API_ENABLE_EVT */ + bta_sdp_search, /* BTA_SDP_API_SEARCH_EVT */ + bta_sdp_create_record, /* BTA_SDP_API_CREATE_RECORD_USER_EVT */ + bta_sdp_remove_record, /* BTA_SDP_API_REMOVE_RECORD_USER_EVT */ + bta_sdp_disable, /* BTA_SDP_API_DISABLE_EVT */ }; /******************************************************************************* diff --git a/components/bt/host/bluedroid/bta/sdp/bta_sdp_act.c b/components/bt/host/bluedroid/bta/sdp/bta_sdp_act.c index 70aa00ba751..ba6aad42d61 100644 --- a/components/bt/host/bluedroid/bta/sdp/bta_sdp_act.c +++ b/components/bt/host/bluedroid/bta/sdp/bta_sdp_act.c @@ -363,8 +363,8 @@ static void bta_create_raw_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_RE /* Try to extract a service name */ if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL) { - record->pse.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type); - record->pse.hdr.service_name = (char *)p_attr->attr_value.v.array; + record->hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type); + record->hdr.service_name = (char *)p_attr->attr_value.v.array; } if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM)) != NULL) { @@ -373,9 +373,9 @@ static void bta_create_raw_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_RE /* Try to extract an RFCOMM channel */ if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) { - record->pse.hdr.rfcomm_channel_number = pe.params[0]; + record->hdr.rfcomm_channel_number = pe.params[0]; } - record->hdr.user1_ptr_len = p_bta_sdp_cfg->p_sdp_db->raw_size; + record->hdr.user1_ptr_len = p_bta_sdp_cfg->p_sdp_db->raw_used; record->hdr.user1_ptr = p_bta_sdp_cfg->p_sdp_db->raw_data; } @@ -526,6 +526,10 @@ void bta_sdp_search(tBTA_SDP_MSG *p_data) SDP_InitDiscoveryDb (p_bta_sdp_cfg->p_sdp_db, p_bta_sdp_cfg->sdp_db_size, 1, bta_sdp_search_uuid, 0, NULL); + /* tell SDP to keep the raw data */ + p_bta_sdp_cfg->p_sdp_db->raw_size = p_bta_sdp_cfg->sdp_raw_size; + p_bta_sdp_cfg->p_sdp_db->raw_data = p_bta_sdp_cfg->p_sdp_raw_data; + if (!SDP_ServiceSearchAttributeRequest2(p_data->get_search.bd_addr, p_bta_sdp_cfg->p_sdp_db, bta_sdp_search_cback, (void *)bta_sdp_search_uuid)) { bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_NONE; @@ -558,7 +562,7 @@ void bta_sdp_create_record(tBTA_SDP_MSG *p_data) APPL_TRACE_DEBUG("%s() event: %d\n", __func__, p_data->record.hdr.event); tBTA_SDP_CREATE_RECORD_USER bta_sdp = {0}; bta_sdp.status = BTA_SDP_SUCCESS; - bta_sdp.handle = (int)p_data->record.user_data; + bta_sdp.handle = -1; if (bta_sdp_cb.p_dm_cback) { bta_sdp_cb.p_dm_cback(BTA_SDP_CREATE_RECORD_USER_EVT, (tBTA_SDP *)&bta_sdp, p_data->record.user_data); } @@ -576,10 +580,30 @@ void bta_sdp_create_record(tBTA_SDP_MSG *p_data) void bta_sdp_remove_record(tBTA_SDP_MSG *p_data) { APPL_TRACE_DEBUG("%s() event: %d\n", __func__, p_data->record.hdr.event); + tBTA_SDP_REMOVE_RECORD_USER bta_sdp; + bta_sdp.status = BTA_SDP_SUCCESS; + bta_sdp.handle = -1; + if (bta_sdp_cb.p_dm_cback) { + bta_sdp_cb.p_dm_cback(BTA_SDP_REMOVE_RECORD_USER_EVT, (tBTA_SDP *)&bta_sdp, p_data->record.user_data); + } +} + +/******************************************************************************* +** +** Function bta_sdp_disable +** +** Description Removes an SDP record +** +** Returns void +** +*******************************************************************************/ +void bta_sdp_disable(tBTA_SDP_MSG *p_data) +{ + APPL_TRACE_DEBUG("%s()\n", __func__); tBTA_SDP bta_sdp; bta_sdp.status = BTA_SDP_SUCCESS; if (bta_sdp_cb.p_dm_cback) { - bta_sdp_cb.p_dm_cback(BTA_SDP_REMOVE_RECORD_USER_EVT, &bta_sdp, p_data->record.user_data); + bta_sdp_cb.p_dm_cback(BTA_SDP_DISABLE_EVT, &bta_sdp, NULL); } } diff --git a/components/bt/host/bluedroid/bta/sdp/bta_sdp_api.c b/components/bt/host/bluedroid/bta/sdp/bta_sdp_api.c index cafb1a4a4c2..d46f784bf16 100644 --- a/components/bt/host/bluedroid/bta/sdp/bta_sdp_api.c +++ b/components/bt/host/bluedroid/bta/sdp/bta_sdp_api.c @@ -65,7 +65,9 @@ tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK *p_cback) #if BTA_DYNAMIC_MEMORY == TRUE /* Malloc buffer for SDP configuration structure */ p_bta_sdp_cfg->p_sdp_db = (tSDP_DISCOVERY_DB *)osi_malloc(p_bta_sdp_cfg->sdp_db_size); - if (p_bta_sdp_cfg->p_sdp_db == NULL) { + p_bta_sdp_cfg->p_sdp_raw_data = (UINT8 *)osi_malloc(p_bta_sdp_cfg->sdp_raw_size); + if (p_bta_sdp_cfg->p_sdp_db == NULL || p_bta_sdp_cfg->p_sdp_raw_data == NULL) { + BTA_SdpCleanup(); return BTA_SDP_FAILURE; } #endif @@ -101,15 +103,34 @@ tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK *p_cback) *******************************************************************************/ tBTA_SDP_STATUS BTA_SdpDisable(void) { + BT_HDR *p_buf = NULL; tBTA_SDP_STATUS status = BTA_SDP_SUCCESS; + if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR))) != NULL) { + p_buf->event = BTA_SDP_API_DISABLE_EVT; + bta_sys_sendmsg(p_buf); + status = BTA_SDP_FAILURE; + } + + return status; +} + +tBTA_SDP_STATUS BTA_SdpCleanup(void) +{ bta_sys_deregister(BTA_ID_SDP); #if BTA_DYNAMIC_MEMORY == TRUE /* Free buffer for SDP configuration structure */ - osi_free(p_bta_sdp_cfg->p_sdp_db); - p_bta_sdp_cfg->p_sdp_db = NULL; + if (p_bta_sdp_cfg->p_sdp_db) { + osi_free(p_bta_sdp_cfg->p_sdp_db); + p_bta_sdp_cfg->p_sdp_db = NULL; + } + + if (p_bta_sdp_cfg->p_sdp_raw_data) { + osi_free(p_bta_sdp_cfg->p_sdp_raw_data); + p_bta_sdp_cfg->p_sdp_raw_data = NULL; + } #endif - return (status); + return BTA_SDP_SUCCESS; } /******************************************************************************* diff --git a/components/bt/host/bluedroid/bta/sdp/bta_sdp_cfg.c b/components/bt/host/bluedroid/bta/sdp/bta_sdp_cfg.c index 322b25caece..423905bc50b 100644 --- a/components/bt/host/bluedroid/bta/sdp/bta_sdp_cfg.c +++ b/components/bt/host/bluedroid/bta/sdp/bta_sdp_cfg.c @@ -30,16 +30,24 @@ #define BTA_SDP_DB_SIZE 1500 #endif +#ifndef BTA_SDP_RAW_DATA_SIZE +#define BTA_SDP_RAW_DATA_SIZE 1024 +#endif + #if BTA_DYNAMIC_MEMORY == FALSE +static UINT8 bta_sdp_raw_data[BTA_SDP_RAW_DATA_SIZE]; static UINT8 __attribute__ ((aligned(4))) bta_sdp_db_data[BTA_SDP_DB_SIZE]; #endif /* SDP configuration structure */ tBTA_SDP_CFG bta_sdp_cfg = { + BTA_SDP_RAW_DATA_SIZE, BTA_SDP_DB_SIZE, #if BTA_DYNAMIC_MEMORY == FALSE + bta_sdp_raw_data, (tSDP_DISCOVERY_DB *)bta_sdp_db_data /* The data buffer to keep SDP database */ #else + NULL, NULL #endif }; diff --git a/components/bt/host/bluedroid/bta/sdp/include/bta_sdp_int.h b/components/bt/host/bluedroid/bta/sdp/include/bta_sdp_int.h index cf0eb99cc1e..f350ae372f6 100644 --- a/components/bt/host/bluedroid/bta/sdp/include/bta_sdp_int.h +++ b/components/bt/host/bluedroid/bta/sdp/include/bta_sdp_int.h @@ -42,6 +42,7 @@ enum { BTA_SDP_API_SEARCH_EVT, BTA_SDP_API_CREATE_RECORD_USER_EVT, BTA_SDP_API_REMOVE_RECORD_USER_EVT, + BTA_SDP_API_DISABLE_EVT, BTA_SDP_MAX_INT_EVT }; @@ -105,6 +106,7 @@ extern void bta_sdp_enable (tBTA_SDP_MSG *p_data); extern void bta_sdp_search (tBTA_SDP_MSG *p_data); extern void bta_sdp_create_record(tBTA_SDP_MSG *p_data); extern void bta_sdp_remove_record(tBTA_SDP_MSG *p_data); +extern void bta_sdp_disable(tBTA_SDP_MSG *p_data); #endif ///SDP_INCLUDED == TRUE diff --git a/components/bt/host/bluedroid/btc/profile/std/include/bt_sdp.h b/components/bt/host/bluedroid/btc/profile/std/include/bt_sdp.h index 63ca09a80fb..bc30fb3cf77 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/bt_sdp.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/bt_sdp.h @@ -34,55 +34,43 @@ typedef enum { SDP_TYPE_PBAP_PSE, // Phone Book Profile - Server SDP_TYPE_PBAP_PCE, // Phone Book Profile - Client SDP_TYPE_OPP_SERVER, // Object Push Profile - SDP_TYPE_SAP_SERVER // SIM Access Profile + SDP_TYPE_SAP_SERVER, // SIM Access Profile } bluetooth_sdp_types; -typedef struct _bluetooth_sdp_hdr { - bluetooth_sdp_types type; - esp_bt_uuid_t uuid; - uint32_t service_name_length; - char *service_name; - int32_t rfcomm_channel_number; - int32_t l2cap_psm; - int32_t profile_version; -} bluetooth_sdp_hdr; - /** * Some signals need additional pointers, hence we introduce a * generic way to handle these pointers. */ typedef struct _bluetooth_sdp_hdr_overlay { bluetooth_sdp_types type; - esp_bt_uuid_t bt_uuid; - uint32_t service_name_length; - char *service_name; - int32_t rfcomm_channel_number; - int32_t l2cap_psm; - int32_t profile_version; - - // User pointers, only used for some signals - see bluetooth_sdp_ops_record - int user1_ptr_len; - uint8_t *user1_ptr; - int user2_ptr_len; - uint8_t *user2_ptr; + esp_bt_uuid_t uuid; + uint32_t service_name_length; + char *service_name; + int32_t rfcomm_channel_number; + int32_t l2cap_psm; + int32_t profile_version; + int user1_ptr_len; + uint8_t *user1_ptr; + int user2_ptr_len; // not used + uint8_t *user2_ptr; // not used } bluetooth_sdp_hdr_overlay; typedef struct _bluetooth_sdp_mas_record { bluetooth_sdp_hdr_overlay hdr; - uint32_t mas_instance_id; - uint32_t supported_features; - uint32_t supported_message_types; + uint32_t mas_instance_id; + uint32_t supported_features; + uint32_t supported_message_types; } bluetooth_sdp_mas_record; typedef struct _bluetooth_sdp_mns_record { bluetooth_sdp_hdr_overlay hdr; - uint32_t supported_features; + uint32_t supported_features; } bluetooth_sdp_mns_record; typedef struct _bluetooth_sdp_pse_record { bluetooth_sdp_hdr_overlay hdr; - uint32_t supported_features; - uint32_t supported_repositories; + uint32_t supported_features; + uint32_t supported_repositories; } bluetooth_sdp_pse_record; typedef struct _bluetooth_sdp_pce_record { @@ -91,8 +79,8 @@ typedef struct _bluetooth_sdp_pce_record { typedef struct _bluetooth_sdp_ops_record { bluetooth_sdp_hdr_overlay hdr; - int supported_formats_list_len; - uint8_t supported_formats_list[SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH]; + int supported_formats_list_len; + uint8_t supported_formats_list[SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH]; } bluetooth_sdp_ops_record; typedef struct _bluetooth_sdp_sap_record { @@ -100,13 +88,13 @@ typedef struct _bluetooth_sdp_sap_record { } bluetooth_sdp_sap_record; typedef union { - bluetooth_sdp_hdr_overlay hdr; - bluetooth_sdp_mas_record mas; - bluetooth_sdp_mns_record mns; - bluetooth_sdp_pse_record pse; - bluetooth_sdp_pce_record pce; - bluetooth_sdp_ops_record ops; - bluetooth_sdp_sap_record sap; + bluetooth_sdp_hdr_overlay hdr; + bluetooth_sdp_mas_record mas; + bluetooth_sdp_mns_record mns; + bluetooth_sdp_pse_record pse; + bluetooth_sdp_pce_record pce; + bluetooth_sdp_ops_record ops; + bluetooth_sdp_sap_record sap; } bluetooth_sdp_record; #endif /* __BT_SDP_H__ */ diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_sdp.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_sdp.h index 60772fa3c4c..fa117988e98 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_sdp.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_sdp.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -32,9 +32,9 @@ typedef union { } search; //BTC_SDP_ACT_CREATE_RECORD - struct creat_record_arg { + struct create_record_arg { bluetooth_sdp_record *record; - } creat_record; + } create_record; //BTC_SDP_ACT_REMOVE_RECORD struct remove_record_arg { diff --git a/components/bt/host/bluedroid/btc/profile/std/sdp/btc_sdp.c b/components/bt/host/bluedroid/btc/profile/std/sdp/btc_sdp.c index 6eaf6cfb52b..9714e0025ab 100644 --- a/components/bt/host/bluedroid/btc/profile/std/sdp/btc_sdp.c +++ b/components/bt/host/bluedroid/btc/profile/std/sdp/btc_sdp.c @@ -25,12 +25,14 @@ typedef enum { } sdp_state_t; typedef struct { - sdp_state_t state; + uint8_t state; int sdp_handle; - bluetooth_sdp_record* record_data; + esp_bt_uuid_t uuid; + void* record_data; } sdp_slot_t; typedef struct { + bool search_allowed; sdp_slot_t *sdp_slots[SDP_MAX_RECORDS]; osi_mutex_t sdp_slot_mutex; } sdp_local_param_t; @@ -48,6 +50,21 @@ static sdp_local_param_t *sdp_local_param_ptr; #define is_sdp_init() (&sdp_local_param != NULL && sdp_local_param.sdp_slot_mutex != NULL) #endif +static void btc_sdp_cleanup(void) +{ +#if SDP_DYNAMIC_MEMORY == TRUE + if (sdp_local_param_ptr) { +#endif + if (sdp_local_param.sdp_slot_mutex) { + osi_mutex_free(&sdp_local_param.sdp_slot_mutex); + sdp_local_param.sdp_slot_mutex = NULL; + } +#if SDP_DYNAMIC_MEMORY == TRUE + osi_free(sdp_local_param_ptr); + sdp_local_param_ptr = NULL; + } +#endif +} static inline void btc_sdp_cb_to_app(esp_sdp_cb_event_t event, esp_sdp_cb_param_t *param) { @@ -57,46 +74,25 @@ static inline void btc_sdp_cb_to_app(esp_sdp_cb_event_t event, esp_sdp_cb_param_ } } -static void sdp_disable_handler(void) -{ - btc_msg_t msg; - bt_status_t status; - - msg.sig = BTC_SIG_API_CB; - msg.pid = BTC_PID_SDP; - msg.act = BTA_SDP_DISENABLE_EVT; - - status = btc_transfer_context(&msg, NULL, 0, NULL, NULL); - - if (status != BT_STATUS_SUCCESS) { - BTC_TRACE_ERROR("%s btc_transfer_context failed", __func__); - } -} - -static int get_sdp_records_size(bluetooth_sdp_record* in_record, int count) +static int get_sdp_record_size(bluetooth_sdp_record* in_record) { - bluetooth_sdp_record* record = in_record; + bluetooth_sdp_record *record = in_record; int records_size = 0; - for(int i = 0; i < count; i++) { - record = &in_record[i]; - records_size += sizeof(bluetooth_sdp_record); - records_size += record->hdr.service_name_length; - if(record->hdr.service_name_length > 0){ - records_size++; /* + '\0' termination of string */ - } - records_size += record->hdr.user1_ptr_len; - records_size += record->hdr.user2_ptr_len; + records_size += sizeof(bluetooth_sdp_record); + records_size += record->hdr.service_name_length; + if (record->hdr.service_name_length > 0) { + records_size++; /* + '\0' termination of string */ } return records_size; } -static void set_sdp_handle(int id, int handle) +static void set_sdp_slot_info(int id, int sdp_handle, esp_bt_uuid_t *uuid) { sdp_slot_t *slot = NULL; - BTC_TRACE_DEBUG("%s() id=%d to handle=0x%08x", __func__, id, handle); + BTC_TRACE_DEBUG("%s() id=%d to sdp_handle=0x%08x", __func__, id, sdp_handle); if(id >= SDP_MAX_RECORDS) { BTC_TRACE_ERROR("%s() failed - id %d is invalid", __func__, id); @@ -104,34 +100,64 @@ static void set_sdp_handle(int id, int handle) } osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); - slot = sdp_local_param.sdp_slots[id]; - if (slot == NULL) { - osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); - BTC_TRACE_ERROR("%s() id=%d to handle=0x%08x, set failed", __func__, id, handle); - return; - } - slot->sdp_handle = handle; + + do { + slot = sdp_local_param.sdp_slots[id]; + if (slot == NULL) { + BTC_TRACE_ERROR("%s() id = %d ", __func__, id); + break; + } + + if (slot->state != SDP_RECORD_ALLOCED) { + BTC_TRACE_ERROR("%s() failed - state for id %d is state = %d expected %d", __func__, id, + sdp_local_param.sdp_slots[id]->state, SDP_RECORD_ALLOCED); + break; + } + slot->sdp_handle = sdp_handle; + slot->record_data = NULL; + if (uuid) { + memcpy(&slot->uuid, uuid, sizeof(esp_bt_uuid_t)); + } else { + memset(&slot->uuid, 0, sizeof(esp_bt_uuid_t)); + } + } while (0); + osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); } - -static bool get_sdp_record_by_handle(int handle, bluetooth_sdp_record* record) +static void get_sdp_slot_info(int id, int *sdp_handle, esp_bt_uuid_t *uuid) { sdp_slot_t *slot = NULL; + if(id >= SDP_MAX_RECORDS) { + BTC_TRACE_ERROR("%s() failed - id %d is invalid", __func__, id); + return; + } + osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); - for (int i = 0; i < SDP_MAX_RECORDS; i++) { - slot = sdp_local_param.sdp_slots[i]; - if ((slot != NULL) && (slot->sdp_handle == handle)) { - memcpy(record, slot->record_data, sizeof(bluetooth_sdp_record)); - osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); - return true; + do { + slot = sdp_local_param.sdp_slots[id]; + if (slot == NULL) { + break; } - } + + if (slot->state != SDP_RECORD_ALLOCED) { + BTC_TRACE_ERROR("%s() failed - state for id %d is state = %d expected %d", __func__, id, + sdp_local_param.sdp_slots[id]->state, SDP_RECORD_ALLOCED); + break; + } + + if (sdp_handle) { + *sdp_handle = slot->sdp_handle; + } + + if (uuid) { + memcpy(uuid, &slot->uuid, sizeof(esp_bt_uuid_t)); + } + } while (0); osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); - return false; } static int get_sdp_slot_id_by_handle(int handle) @@ -152,9 +178,10 @@ static int get_sdp_slot_id_by_handle(int handle) return -1; } -static sdp_slot_t *start_create_sdp(int id) +static bluetooth_sdp_record *start_create_sdp(int id) { - sdp_slot_t *sdp_slot = NULL; + sdp_slot_t *slot = NULL; + bluetooth_sdp_record* record_data = NULL; if(id >= SDP_MAX_RECORDS) { BTC_TRACE_ERROR("%s() failed - id %d is invalid", __func__, id); @@ -162,62 +189,58 @@ static sdp_slot_t *start_create_sdp(int id) } osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); - sdp_slot = sdp_local_param.sdp_slots[id]; - if (sdp_slot == NULL) { - BTC_TRACE_ERROR("%s() id = %d ", __func__, id); - } else if(sdp_slot->state != SDP_RECORD_ALLOCED) { - BTC_TRACE_ERROR("%s() failed - state for id %d is state = %d expected %d", __func__, - id, sdp_local_param.sdp_slots[id]->state, SDP_RECORD_ALLOCED); - /* The record have been removed before this event occurred - e.g. deinit */ - sdp_slot = NULL; - } + + do { + slot = sdp_local_param.sdp_slots[id]; + if (slot == NULL) { + BTC_TRACE_ERROR("%s() id = %d ", __func__, id); + break; + } + + if (slot->state != SDP_RECORD_ALLOCED) { + BTC_TRACE_ERROR("%s() failed - state for id %d is state = %d expected %d", __func__, id, + sdp_local_param.sdp_slots[id]->state, SDP_RECORD_ALLOCED); + break; + } + record_data = slot->record_data; + } while (0); + osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); - return sdp_slot; + return record_data; } /* Deep copy all content of in_records into out_records. * out_records must point to a chunk of memory large enough to contain all * the data. Use getSdpRecordsSize() to calculate the needed size. */ -static void copy_sdp_records(bluetooth_sdp_record* in_records, bluetooth_sdp_record* out_records, int count) +static void copy_sdp_record_common(bluetooth_sdp_record* in_record, bluetooth_sdp_record* out_record) { - bluetooth_sdp_record *in_record; - bluetooth_sdp_record *out_record; - char *free_ptr = (char*)(&out_records[count]); /* set pointer to after the last entry */ - - for(int i = 0; i < count; i++) { - in_record = &in_records[i]; - out_record = &out_records[i]; - *out_record = *in_record; - - if(in_record->hdr.service_name == NULL || in_record->hdr.service_name_length == 0) { - out_record->hdr.service_name = NULL; - out_record->hdr.service_name_length = 0; - } else { - out_record->hdr.service_name = free_ptr; // Update service_name pointer - // Copy string - memcpy(free_ptr, in_record->hdr.service_name, in_record->hdr.service_name_length); - free_ptr += in_record->hdr.service_name_length; - *(free_ptr) = '\0'; // Set '\0' termination of string - free_ptr++; - } - if(in_record->hdr.user1_ptr != NULL) { - out_record->hdr.user1_ptr = (UINT8*)free_ptr; // Update pointer - memcpy(free_ptr, in_record->hdr.user1_ptr, in_record->hdr.user1_ptr_len); // Copy content - free_ptr += in_record->hdr.user1_ptr_len; - } - if(in_record->hdr.user2_ptr != NULL) { - out_record->hdr.user2_ptr = (UINT8*)free_ptr; // Update pointer - memcpy(free_ptr, in_record->hdr.user2_ptr, in_record->hdr.user2_ptr_len); // Copy content - free_ptr += in_record->hdr.user2_ptr_len; - } + uint8_t *free_ptr = (uint8_t *)(out_record + 1); /* set pointer to after the last entry */ + + memcpy(out_record, in_record, sizeof(bluetooth_sdp_record)); + + if (in_record->hdr.service_name == NULL || in_record->hdr.service_name_length == 0) { + out_record->hdr.service_name = NULL; + out_record->hdr.service_name_length = 0; + } else { + out_record->hdr.service_name = (char *)free_ptr; // Update service_name pointer + // Copy string + memcpy(free_ptr, in_record->hdr.service_name, in_record->hdr.service_name_length); + free_ptr += in_record->hdr.service_name_length; + *(free_ptr) = '\0'; // Set '\0' termination of string + free_ptr++; } } +static void copy_sdp_record(bluetooth_sdp_record* in_record, bluetooth_sdp_record* out_record) +{ + copy_sdp_record_common(in_record, out_record); +} + static int alloc_sdp_slot(bluetooth_sdp_record* in_record) { int i; - int record_size = get_sdp_records_size(in_record, 1); + int record_size = get_sdp_record_size(in_record); bluetooth_sdp_record *record = NULL; sdp_slot_t **slot = NULL; @@ -227,11 +250,10 @@ static int alloc_sdp_slot(bluetooth_sdp_record* in_record) return -1; } - copy_sdp_records(in_record, record, 1); + copy_sdp_record(in_record, record); osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); - for(i = 0; i < SDP_MAX_RECORDS; i++) - { + for (i = 0; i < SDP_MAX_RECORDS; i++) { slot = &sdp_local_param.sdp_slots[i]; if ((*slot) == NULL) { if (((*slot) = (sdp_slot_t *)osi_malloc(sizeof(sdp_slot_t))) == NULL) { @@ -240,8 +262,8 @@ static int alloc_sdp_slot(bluetooth_sdp_record* in_record) osi_free(record); return -1; } - (*slot)->state = SDP_RECORD_ALLOCED; - (*slot)->record_data = record; + (*slot)->state = SDP_RECORD_ALLOCED; + (*slot)->record_data = record; break; } } @@ -292,7 +314,7 @@ static int free_sdp_slot(int id) } /* Create a raw SDP record based on information stored in a bluetooth_sdp_raw_record */ -static int add_raw_sdp(const bluetooth_sdp_record* rec) +static int add_raw_sdp(const bluetooth_sdp_record *rec) { tSDP_PROTOCOL_ELEM protoList [2]; UINT16 browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP; @@ -301,6 +323,7 @@ static int add_raw_sdp(const bluetooth_sdp_record* rec) UINT8 temp[LEN_UUID_128]; UINT8* p_temp = temp; UINT32 sdp_handle = 0; + const esp_bt_uuid_t *p_uuid = &rec->hdr.uuid; BTC_TRACE_DEBUG("%s(): scn 0x%02x, psm = 0x%04x\n service name %s", __func__, rec->hdr.rfcomm_channel_number, rec->hdr.l2cap_psm, rec->hdr.service_name); @@ -310,15 +333,15 @@ static int add_raw_sdp(const bluetooth_sdp_record* rec) return sdp_handle; } - if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_16) { + if (p_uuid->len == ESP_UUID_LEN_16) { UINT8_TO_BE_STREAM (p_temp, (UUID_DESC_TYPE << 3) | SIZE_TWO_BYTES); - UINT16_TO_BE_STREAM (p_temp, rec->hdr.bt_uuid.uuid.uuid16); - } else if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_32) { + UINT16_TO_BE_STREAM (p_temp, p_uuid->uuid.uuid16); + } else if (p_uuid->len == ESP_UUID_LEN_32) { UINT8_TO_BE_STREAM (p_temp, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES); - UINT32_TO_BE_STREAM (p_temp, rec->hdr.bt_uuid.uuid.uuid32); - } else if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_128) { + UINT32_TO_BE_STREAM (p_temp, p_uuid->uuid.uuid32); + } else if (p_uuid->len == ESP_UUID_LEN_128) { UINT8_TO_BE_STREAM (p_temp, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES); - ARRAY_TO_BE_STREAM (p_temp, rec->hdr.bt_uuid.uuid.uuid128, LEN_UUID_128); + ARRAY_TO_BE_STREAM (p_temp, p_uuid->uuid.uuid128, LEN_UUID_128); } else { SDP_DeleteRecord(sdp_handle); sdp_handle = 0; @@ -357,7 +380,7 @@ static int add_raw_sdp(const bluetooth_sdp_record* rec) UINT_DESC_TYPE, (UINT32)2, temp); } - /* Make the service browseable */ + /* Make the service browsable */ status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); if (!status) { @@ -365,12 +388,12 @@ static int add_raw_sdp(const bluetooth_sdp_record* rec) sdp_handle = 0; BTC_TRACE_ERROR("%s() FAILED, status = %d", __func__, status); } else { - if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_16) { - bta_sys_add_uuid(rec->hdr.bt_uuid.uuid.uuid16); - } else if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_32) { - bta_sys_add_uuid_32(rec->hdr.bt_uuid.uuid.uuid32); - } else if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_128) { - bta_sys_add_uuid_128((UINT8 *)&rec->hdr.bt_uuid.uuid.uuid128); + if (p_uuid->len == ESP_UUID_LEN_16) { + bta_sys_add_uuid(p_uuid->uuid.uuid16); + } else if (p_uuid->len == ESP_UUID_LEN_32) { + bta_sys_add_uuid_32(p_uuid->uuid.uuid32); + } else if (p_uuid->len == ESP_UUID_LEN_128) { + bta_sys_add_uuid_128((UINT8 *)&p_uuid->uuid.uuid128); } BTC_TRACE_DEBUG("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle); } @@ -448,7 +471,7 @@ static int add_maps_sdp(const bluetooth_sdp_mas_record* rec) UINT_DESC_TYPE, (UINT32)2, temp); } - /* Make the service browseable */ + /* Make the service browsable */ status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); if (!status) { @@ -523,7 +546,7 @@ static int add_mapc_sdp(const bluetooth_sdp_mns_record* rec) UINT_DESC_TYPE, (UINT32)2, temp); } - /* Make the service browseable */ + /* Make the service browsable */ status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); if (!status) { @@ -603,7 +626,7 @@ static int add_pbaps_sdp(const bluetooth_sdp_pse_record* rec) UINT_DESC_TYPE, (UINT32)2, temp); } - /* Make the service browseable */ + /* Make the service browsable */ status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); if (!status) { @@ -649,7 +672,7 @@ static int add_pbapc_sdp(const bluetooth_sdp_pce_record* rec) UUID_SERVCLASS_PHONE_ACCESS, rec->hdr.profile_version); - /* Make the service browseable */ + /* Make the service browsable */ status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); if (!status) { @@ -736,7 +759,7 @@ static int add_opps_sdp(const bluetooth_sdp_ops_record* rec) UINT_DESC_TYPE, (UINT32)2, temp); } - /* Make the service browseable */ + /* Make the service browsable */ status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); if (!status) { @@ -799,7 +822,7 @@ static int add_saps_sdp(const bluetooth_sdp_sap_record* rec) UUID_SERVCLASS_SAP, rec->hdr.profile_version); - // Make the service browseable + // Make the service browsable status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); if (!status) { @@ -816,64 +839,183 @@ static int add_saps_sdp(const bluetooth_sdp_sap_record* rec) static int btc_handle_create_record_event(int id) { - int handle = -1; - const sdp_slot_t *sdp_slot = NULL; + int sdp_handle = 0; + bluetooth_sdp_record *record = start_create_sdp(id); + esp_bt_uuid_t service_uuid = {0}; BTC_TRACE_DEBUG("Sdp Server %s", __func__); - sdp_slot = start_create_sdp(id); - if(sdp_slot != NULL) { - bluetooth_sdp_record* record = sdp_slot->record_data; - switch(record->hdr.type) { + if (record != NULL) { + switch (record->hdr.type) { case SDP_TYPE_RAW: - handle = add_raw_sdp(record); + sdp_handle = add_raw_sdp(record); + memcpy(&service_uuid, &record->hdr.uuid, sizeof(esp_bt_uuid_t)); break; case SDP_TYPE_MAP_MAS: - handle = add_maps_sdp(&record->mas); + sdp_handle = add_maps_sdp(&record->mas); + service_uuid.len = ESP_UUID_LEN_16; + service_uuid.uuid.uuid16 = UUID_SERVCLASS_MESSAGE_ACCESS; break; case SDP_TYPE_MAP_MNS: - handle = add_mapc_sdp(&record->mns); + sdp_handle = add_mapc_sdp(&record->mns); + service_uuid.len = ESP_UUID_LEN_16; + service_uuid.uuid.uuid16 = UUID_SERVCLASS_MESSAGE_NOTIFICATION; break; case SDP_TYPE_PBAP_PSE: - handle = add_pbaps_sdp(&record->pse); + sdp_handle = add_pbaps_sdp(&record->pse); + service_uuid.len = ESP_UUID_LEN_16; + service_uuid.uuid.uuid16 = UUID_SERVCLASS_PBAP_PSE; break; case SDP_TYPE_PBAP_PCE: - handle = add_pbapc_sdp(&record->pce); + sdp_handle = add_pbapc_sdp(&record->pce); + service_uuid.len = ESP_UUID_LEN_16; + service_uuid.uuid.uuid16 = UUID_SERVCLASS_PBAP_PCE; break; case SDP_TYPE_OPP_SERVER: - handle = add_opps_sdp(&record->ops); + sdp_handle = add_opps_sdp(&record->ops); + service_uuid.len = ESP_UUID_LEN_16; + service_uuid.uuid.uuid16 = UUID_SERVCLASS_OBEX_OBJECT_PUSH; break; case SDP_TYPE_SAP_SERVER: - handle = add_saps_sdp(&record->sap); + sdp_handle = add_saps_sdp(&record->sap); + service_uuid.len = ESP_UUID_LEN_16; + service_uuid.uuid.uuid16 = UUID_SERVCLASS_SAP; break; default: - BTC_TRACE_DEBUG("Record type %d is not supported",record->hdr.type); + BTC_TRACE_DEBUG("Record type %d is not supported", record->hdr.type); break; } - if(handle != -1) { - set_sdp_handle(id, handle); + + if(sdp_handle != 0) { + set_sdp_slot_info(id, sdp_handle, &service_uuid); + // free the record, since not use it anymore + osi_free(record); + } else { + sdp_handle = -1; } + } else { + sdp_handle = -1; } - return handle; + if (sdp_handle == -1) { + free_sdp_slot(id); + } + + return sdp_handle; } -static bool btc_sdp_remove_record_event(int handle) +static bool btc_sdp_remove_record_event(int id, int *p_sdp_handle) { + BTC_TRACE_DEBUG("Sdp Server %s", __func__); + bool result = false; + int sdp_handle = -1; + esp_bt_uuid_t service_uuid = {0}; - BTC_TRACE_DEBUG("Sdp Server %s", __func__); + get_sdp_slot_info(id, &sdp_handle, &service_uuid); - if(handle != -1 && handle != 0) { - result = SDP_DeleteRecord(handle); - if(result == false) { - BTC_TRACE_ERROR(" Unable to remove handle 0x%08x", handle); + if (sdp_handle > 0) { + do { + result = SDP_DeleteRecord(sdp_handle); + if (!result) { + BTC_TRACE_ERROR("Unable to remove handle 0x%08x", sdp_handle); + break; + } + + if (service_uuid.len == ESP_UUID_LEN_16) { + bta_sys_remove_uuid(service_uuid.uuid.uuid16); + } else if (service_uuid.len == ESP_UUID_LEN_32) { + bta_sys_remove_uuid_32(service_uuid.uuid.uuid32); + } else if (service_uuid.len == ESP_UUID_LEN_128) { + bta_sys_remove_uuid_128((UINT8 *)&service_uuid.uuid.uuid128); + } + } while (0); + + if (p_sdp_handle) { + *p_sdp_handle = sdp_handle; } } return result; } +static void btc_sdp_cb_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) +{ + switch (msg->act) { + case BTA_SDP_SEARCH_COMP_EVT: { + tBTA_SDP_SEARCH_COMP *src_search_comp = (tBTA_SDP_SEARCH_COMP *)p_src; + tBTA_SDP_SEARCH_COMP *dest_search_comp = (tBTA_SDP_SEARCH_COMP *)p_dest; + int record_count = src_search_comp->record_count; + + for (int i = 0; i < record_count; i++) { + bluetooth_sdp_record *src_record = &src_search_comp->records[i]; + bluetooth_sdp_record *dest_record = &dest_search_comp->records[i]; + // deep copy service name + uint32_t src_service_name_length = src_record->hdr.service_name_length; + char *src_service_name = src_record->hdr.service_name; + dest_record->hdr.service_name_length = 0; + dest_record->hdr.service_name = NULL; + if (src_service_name && src_service_name_length) { + char *service_name = (char *)osi_malloc(src_service_name_length + 1); + if (service_name) { + memcpy(service_name, src_service_name, src_service_name_length); + service_name[src_service_name_length] = '\0'; + + dest_record->hdr.service_name_length = src_service_name_length; + dest_record->hdr.service_name = service_name; + } else { + BTC_TRACE_ERROR("%s malloc service name failed, orig service name:%s", __func__, src_service_name); + } + } + + // deep copy user1_ptr fow RAW type + int src_user1_ptr_len = src_record->hdr.user1_ptr_len; + uint8_t *src_user1_ptr = src_record->hdr.user1_ptr; + dest_record->hdr.user1_ptr_len = 0; + dest_record->hdr.user1_ptr = NULL; + if (src_record->hdr.type == SDP_TYPE_RAW && src_user1_ptr && src_user1_ptr_len) { + uint8_t *user1_ptr = (uint8_t *)osi_malloc(src_user1_ptr_len); + if (user1_ptr) { + memcpy(user1_ptr, src_user1_ptr, src_user1_ptr_len); + + dest_record->hdr.user1_ptr_len = src_user1_ptr_len; + dest_record->hdr.user1_ptr = user1_ptr; + } else { + BTC_TRACE_ERROR("%s malloc user1_ptr failed", __func__); + } + } + } + + break; + } + default: + break; + } +} + +static void btc_sdp_cb_arg_deep_free(btc_msg_t *msg) +{ + switch (msg->act) { + case BTA_SDP_SEARCH_COMP_EVT: { + tBTA_SDP_SEARCH_COMP *search_comp = (tBTA_SDP_SEARCH_COMP *)msg->arg; + for (size_t i = 0; i < search_comp->record_count; i++) { + bluetooth_sdp_record *record = &search_comp->records[i]; + if (record->hdr.service_name) { + osi_free(record->hdr.service_name); + } + + if (record->hdr.user1_ptr) { + osi_free(record->hdr.user1_ptr); + } + } + + break; + } + default: + break; + } +} + static void btc_sdp_dm_cback(tBTA_SDP_EVT event, tBTA_SDP* p_data, void* user_data) { btc_msg_t msg; @@ -881,18 +1023,18 @@ static void btc_sdp_dm_cback(tBTA_SDP_EVT event, tBTA_SDP* p_data, void* user_da switch (event) { case BTA_SDP_CREATE_RECORD_USER_EVT: { - if (p_data->status == BTA_SDP_SUCCESS) { + if (p_data->sdp_create_record.status == BTA_SDP_SUCCESS) { p_data->sdp_create_record.handle = btc_handle_create_record_event((int)user_data); if (p_data->sdp_create_record.handle < 0) { - p_data->status = BTA_SDP_FAILURE; + p_data->sdp_create_record.status = BTA_SDP_FAILURE; } } } break; case BTA_SDP_REMOVE_RECORD_USER_EVT: { - if (p_data->status == BTA_SDP_SUCCESS) { - if (btc_sdp_remove_record_event((int)user_data) == false) { - p_data->status = BTA_SDP_FAILURE; + if (p_data->sdp_remove_record.status == BTA_SDP_SUCCESS) { + if (btc_sdp_remove_record_event((int)user_data, &p_data->sdp_remove_record.handle) == false) { + p_data->sdp_remove_record.status = BTA_SDP_FAILURE; } } } @@ -905,7 +1047,7 @@ static void btc_sdp_dm_cback(tBTA_SDP_EVT event, tBTA_SDP* p_data, void* user_da msg.pid = BTC_PID_SDP; msg.act = event; - status = btc_transfer_context(&msg, p_data, sizeof(tBTA_SDP), NULL, NULL); + status = btc_transfer_context(&msg, p_data, sizeof(tBTA_SDP), btc_sdp_cb_arg_deep_copy, btc_sdp_cb_arg_deep_free); if (status != BT_STATUS_SUCCESS) { BTC_TRACE_ERROR("%s btc_transfer_context failed", __func__); @@ -930,23 +1072,27 @@ static void btc_sdp_init(void) ret = ESP_SDP_NO_RESOURCE; break; } - memset((void *)sdp_local_param_ptr, 0, sizeof(sdp_local_param_t)); #endif + memset(&sdp_local_param, 0, sizeof(sdp_local_param_t)); if (osi_mutex_new(&sdp_local_param.sdp_slot_mutex) != 0) { -#if SDP_DYNAMIC_MEMORY == TRUE - osi_free(sdp_local_param_ptr); - sdp_local_param_ptr = NULL; -#endif BTC_TRACE_ERROR("%s osi_mutex_new failed\n", __func__); ret = ESP_SDP_NO_RESOURCE; break; } ret = BTA_SdpEnable(btc_sdp_dm_cback); + if (ret != ESP_SDP_SUCCESS) { + BTC_TRACE_ERROR("%s BTA_SdpEnable failed, ret = %d\n", __func__, ret); + ret = ESP_SDP_FAILURE; + break; + } + + sdp_local_param.search_allowed = true; } while(0); if (ret != ESP_SDP_SUCCESS) { + btc_sdp_cleanup(); param.init.status = ret; btc_sdp_cb_to_app(ESP_SDP_INIT_EVT, ¶m); } @@ -956,7 +1102,6 @@ static void btc_sdp_deinit(void) { esp_sdp_cb_param_t param; esp_sdp_status_t ret = ESP_SDP_SUCCESS; - int handle; do { if (!is_sdp_init()) { @@ -966,12 +1111,13 @@ static void btc_sdp_deinit(void) } for(int i = 0; i < SDP_MAX_RECORDS; i++) { - handle = free_sdp_slot(i); - if (handle > 0) { - BTA_SdpRemoveRecordByUser((void*)handle); + int sdp_handle = -1; + get_sdp_slot_info(i, &sdp_handle, NULL); + if (sdp_handle > 0) { + BTA_SdpRemoveRecordByUser((void*)i); } } - sdp_disable_handler(); + BTA_SdpDisable(); } while(0); if (ret != ESP_SDP_SUCCESS) { @@ -982,7 +1128,7 @@ static void btc_sdp_deinit(void) static void btc_sdp_create_record(btc_sdp_args_t *arg) { - int handle; + int slot_id; esp_sdp_cb_param_t param; esp_sdp_status_t ret = ESP_SDP_SUCCESS; @@ -993,13 +1139,13 @@ static void btc_sdp_create_record(btc_sdp_args_t *arg) break; } - handle = alloc_sdp_slot(arg->creat_record.record); - if (handle < 0) { + slot_id = alloc_sdp_slot(arg->create_record.record); + if (slot_id < 0) { ret = ESP_SDP_FAILURE; break; } - BTA_SdpCreateRecordByUser((void *) handle); + BTA_SdpCreateRecordByUser((void *) slot_id); } while(0); if (ret != ESP_SDP_SUCCESS) { @@ -1011,7 +1157,6 @@ static void btc_sdp_create_record(btc_sdp_args_t *arg) static void btc_sdp_remove_record(btc_sdp_args_t *arg) { - int handle; esp_sdp_cb_param_t param; esp_sdp_status_t ret = ESP_SDP_SUCCESS; @@ -1022,42 +1167,16 @@ static void btc_sdp_remove_record(btc_sdp_args_t *arg) break; } - bluetooth_sdp_record rec; - if (get_sdp_record_by_handle(arg->remove_record.record_handle, &rec)) { - if (rec.hdr.bt_uuid.len == ESP_UUID_LEN_16) { - bta_sys_remove_uuid(rec.hdr.bt_uuid.uuid.uuid16); - } else if (rec.hdr.bt_uuid.len == ESP_UUID_LEN_32) { - bta_sys_remove_uuid_32(rec.hdr.bt_uuid.uuid.uuid32); - } else if (rec.hdr.bt_uuid.len == ESP_UUID_LEN_128) { - bta_sys_remove_uuid_128((UINT8 *)&rec.hdr.bt_uuid.uuid.uuid128); - } - } else { - BTC_TRACE_ERROR("%s SDP record with handle %d not found", - __func__, arg->remove_record.record_handle); - ret = ESP_SDP_NO_CREATE_RECORD; - break; - } - /* Get the Record handle, and free the slot */ /* The application layer record_handle is equivalent to the id of the btc layer */ - int slot = get_sdp_slot_id_by_handle(arg->remove_record.record_handle); - if (slot < 0) { + int slot_id = get_sdp_slot_id_by_handle(arg->remove_record.record_handle); + if (slot_id < 0) { + BTC_TRACE_ERROR("%s SDP record with handle %d not found", __func__, arg->remove_record.record_handle); ret = ESP_SDP_NO_CREATE_RECORD; break; } - handle = free_sdp_slot(slot); - - BTC_TRACE_DEBUG("Sdp Server %s id=%d to handle=0x%08x", - __func__, arg->remove_record.record_handle, handle); - - /* Pass the actual record handle */ - if(handle > 0) { - BTA_SdpRemoveRecordByUser((void*) handle); - } else { - ret = ESP_SDP_NO_CREATE_RECORD; - break; - } + BTA_SdpRemoveRecordByUser((void *)slot_id); } while(0); if (ret != ESP_SDP_SUCCESS) { @@ -1078,7 +1197,18 @@ static void btc_sdp_search(btc_sdp_args_t *arg) break; } + if (!sdp_local_param.search_allowed) { + BTC_TRACE_ERROR("%s SDP search is not allowed!", __func__); + ret = ESP_SDP_NO_RESOURCE; + break; + } + BTA_SdpSearch(arg->search.bd_addr, &arg->search.sdp_uuid); + /** + * ESP_SDP_SEARCH_COMP_EVT will refer service name in BTA sdp database, so it is not allowed to be search until + * the previous search is completed + */ + sdp_local_param.search_allowed = false; } while(0); if (ret != ESP_SDP_SUCCESS) { @@ -1089,26 +1219,21 @@ static void btc_sdp_search(btc_sdp_args_t *arg) void btc_sdp_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) { - btc_sdp_args_t *dst = (btc_sdp_args_t *)p_dest; - btc_sdp_args_t *src = (btc_sdp_args_t *)p_src; - switch (msg->act) { - case BTC_SDP_ACT_CREATE_RECORD: - dst->creat_record.record = (bluetooth_sdp_record *)osi_calloc(sizeof(bluetooth_sdp_record)); - if (dst->creat_record.record) { - memcpy(dst->creat_record.record, src->creat_record.record, sizeof(bluetooth_sdp_record)); + case BTC_SDP_ACT_CREATE_RECORD: { + bluetooth_sdp_record **dst_record = &((btc_sdp_args_t *)p_dest)->create_record.record; + bluetooth_sdp_record *src_record = ((btc_sdp_args_t *)p_src)->create_record.record; + bluetooth_sdp_record *record = (bluetooth_sdp_record *)osi_calloc(get_sdp_record_size(src_record)); + if (record) { + copy_sdp_record(src_record, record); } else { BTC_TRACE_ERROR("%s %d osi_malloc failed\n", __func__, msg->act); break; } - dst->creat_record.record->hdr.service_name = (char *)osi_calloc(src->creat_record.record->hdr.service_name_length); - if (dst->creat_record.record->hdr.service_name) { - strcpy(dst->creat_record.record->hdr.service_name, src->creat_record.record->hdr.service_name); - } else { - BTC_TRACE_ERROR("%s %d osi_malloc failed\n", __func__, msg->act); - } + *dst_record = record; break; + } default: break; } @@ -1116,17 +1241,15 @@ void btc_sdp_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) void btc_sdp_arg_deep_free(btc_msg_t *msg) { - btc_sdp_args_t *arg = (btc_sdp_args_t *)msg->arg; - switch (msg->act) { - case BTC_SDP_ACT_CREATE_RECORD: - if (arg->creat_record.record) { - osi_free(arg->creat_record.record); - } - if (arg->creat_record.record->hdr.service_name) { - osi_free(arg->creat_record.record->hdr.service_name); + case BTC_SDP_ACT_CREATE_RECORD: { + btc_sdp_args_t *arg = (btc_sdp_args_t *)msg->arg; + bluetooth_sdp_record *record = arg->create_record.record; + if (record) { + osi_free(record); } break; + } default: break; } @@ -1172,35 +1295,22 @@ void btc_sdp_cb_handler(btc_msg_t *msg) param.init.status = p_data->status; btc_sdp_cb_to_app(ESP_SDP_INIT_EVT, ¶m); break; - case BTA_SDP_DISENABLE_EVT: - BTA_SdpDisable(); - osi_mutex_free(&sdp_local_param.sdp_slot_mutex); - #if SDP_DYNAMIC_MEMORY == TRUE - osi_free(sdp_local_param_ptr); - sdp_local_param_ptr = NULL; - #endif + case BTA_SDP_DISABLE_EVT: + BTA_SdpCleanup(); + btc_sdp_cleanup(); param.deinit.status = ESP_SDP_SUCCESS; btc_sdp_cb_to_app(ESP_SDP_DEINIT_EVT, ¶m); break; case BTA_SDP_SEARCH_COMP_EVT: + // SDP search completed, now can be searched again + sdp_local_param.search_allowed = true; + param.search.status = p_data->sdp_search_comp.status; - if (param.search.status == ESP_SDP_SUCCESS) { - memcpy(param.search.remote_addr, p_data->sdp_search_comp.remote_addr, sizeof(BD_ADDR)); - memcpy(¶m.search.sdp_uuid, &p_data->sdp_search_comp.uuid, sizeof(tSDP_UUID)); - param.search.record_count = p_data->sdp_search_comp.record_count; - param.search.records = osi_malloc(sizeof(esp_bluetooth_sdp_record_t)*p_data->sdp_search_comp.record_count); - if (param.search.records != NULL) { - memcpy(param.search.records, p_data->sdp_search_comp.records, - sizeof(esp_bluetooth_sdp_record_t)*p_data->sdp_search_comp.record_count); - } else { - BTC_TRACE_ERROR("%s %d osi_malloc failed\n", __func__, event); - param.search.status = ESP_SDP_NO_RESOURCE; - } - } + memcpy(param.search.remote_addr, p_data->sdp_search_comp.remote_addr, sizeof(BD_ADDR)); + memcpy(¶m.search.sdp_uuid, &p_data->sdp_search_comp.uuid, sizeof(tSDP_UUID)); + param.search.record_count = p_data->sdp_search_comp.record_count; + param.search.records = (esp_bluetooth_sdp_record_t *)p_data->sdp_search_comp.records; btc_sdp_cb_to_app(ESP_SDP_SEARCH_COMP_EVT, ¶m); - if (param.search.records != NULL) { - osi_free(param.search.records); - } break; case BTA_SDP_CREATE_RECORD_USER_EVT: param.create_record.status = p_data->sdp_create_record.status; @@ -1208,13 +1318,25 @@ void btc_sdp_cb_handler(btc_msg_t *msg) btc_sdp_cb_to_app(ESP_SDP_CREATE_RECORD_COMP_EVT, ¶m); break; case BTA_SDP_REMOVE_RECORD_USER_EVT: - param.remove_record.status = p_data->status; + if (p_data->sdp_remove_record.status == BTA_SDP_SUCCESS) { + int slot_id = get_sdp_slot_id_by_handle(p_data->sdp_remove_record.handle); + if (slot_id < 0) { + p_data->sdp_remove_record.status = ESP_SDP_NO_CREATE_RECORD; + break; + } else { + free_sdp_slot(slot_id); + } + } + + param.remove_record.status = p_data->sdp_remove_record.status; btc_sdp_cb_to_app(ESP_SDP_REMOVE_RECORD_COMP_EVT, ¶m); break; default: BTC_TRACE_DEBUG("%s: Unhandled event (%d)!", __func__, msg->act); break; } + + btc_sdp_cb_arg_deep_free(msg); } #endif ///defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE diff --git a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h index 7108bd98391..171629a75ab 100644 --- a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h +++ b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h @@ -48,16 +48,16 @@ //L2CAP #ifdef CONFIG_BT_L2CAP_ENABLED -#define UC_BT_L2CAP_ENABLED CONFIG_BT_L2CAP_ENABLED +#define UC_BT_L2CAP_ENABLED CONFIG_BT_L2CAP_ENABLED #else -#define UC_BT_L2CAP_ENABLED FALSE +#define UC_BT_L2CAP_ENABLED FALSE #endif //HFP(AG) #ifdef CONFIG_BT_HFP_AG_ENABLE -#define UC_BT_HFP_AG_ENABLED CONFIG_BT_HFP_AG_ENABLE +#define UC_BT_HFP_AG_ENABLED CONFIG_BT_HFP_AG_ENABLE #else -#define UC_BT_HFP_AG_ENABLED FALSE +#define UC_BT_HFP_AG_ENABLED FALSE #endif //HFP(Client) diff --git a/components/bt/host/bluedroid/stack/sdp/sdp_db.c b/components/bt/host/bluedroid/stack/sdp/sdp_db.c index a9b3daa4ca5..60dd04a6b94 100644 --- a/components/bt/host/bluedroid/stack/sdp/sdp_db.c +++ b/components/bt/host/bluedroid/stack/sdp/sdp_db.c @@ -276,7 +276,7 @@ static int sdp_compose_proto_list( UINT8 *p, UINT16 num_elem, ** ** Description This function is called to create a record in the database. ** This would be through the SDP database maintenance API. The -** record is created empty, teh application should then call +** record is created empty, the application should then call ** "add_attribute" to add the record's attributes. ** ** Returns Record handle if OK, else 0. @@ -293,15 +293,15 @@ UINT32 SDP_CreateRecord (void) /* First, check if there is a free record */ if (p_db->num_records < SDP_MAX_RECORDS) { - p_rec =(tSDP_RECORD *)osi_malloc(sizeof(tSDP_RECORD)); - if (p_rec) { - memset(p_rec, 0, sizeof(tSDP_RECORD)); - /* Save previous rec */ - if (p_db->num_records) { - p_rec_prev = list_back(p_db->p_record_list); - } - /* Append new record */ - list_append(p_db->p_record_list, p_rec); + p_rec = (tSDP_RECORD *)osi_malloc(sizeof(tSDP_RECORD)); + if (p_rec) { + memset(p_rec, 0, sizeof(tSDP_RECORD)); + /* Save previous rec */ + if (p_db->num_records) { + p_rec_prev = list_back(p_db->p_record_list); + } + /* Append new record */ + list_append(p_db->p_record_list, p_rec); /* We will use a handle of the first unreserved handle plus last record ** number + 1 */ @@ -321,10 +321,12 @@ UINT32 SDP_CreateRecord (void) 4, buf); return (p_rec->record_handle); - } else { + } + else { SDP_TRACE_ERROR("SDP_CreateRecord fail, memory allocation failed\n"); - } - } else { + } + } + else { SDP_TRACE_ERROR("SDP_CreateRecord fail, exceed maximum records:%d\n", SDP_MAX_RECORDS); } #endif @@ -354,17 +356,17 @@ BOOLEAN SDP_DeleteRecord (UINT32 handle) if (handle == 0 || sdp_cb.server_db.num_records == 0) { /* Delete all records in the database */ sdp_cb.server_db.num_records = 0; - for(p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) { - list_remove(sdp_cb.server_db.p_record_list, p_node); - } + for (p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) { + list_remove(sdp_cb.server_db.p_record_list, p_node); + } /* require new DI record to be created in SDP_SetLocalDiRecord */ sdp_cb.server_db.di_primary_handle = 0; return (TRUE); } else { /* Find the record in the database */ - for(p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) { - p_rec = list_node(p_node); + for (p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) { + p_rec = list_node(p_node); if (p_rec->record_handle == handle) { /* Found it. Shift everything up one */ list_remove(sdp_cb.server_db.p_record_list, p_rec); @@ -374,7 +376,7 @@ BOOLEAN SDP_DeleteRecord (UINT32 handle) SDP_TRACE_DEBUG("SDP_DeleteRecord ok, num_records:%d\n", sdp_cb.server_db.num_records); /* if we're deleting the primary DI record, clear the */ /* value in the control block */ - if ( sdp_cb.server_db.di_primary_handle == handle ) { + if (sdp_cb.server_db.di_primary_handle == handle) { sdp_cb.server_db.di_primary_handle = 0; }