From c5648178626c5d55456b00fb5ec1576ec7d9cb2d Mon Sep 17 00:00:00 2001 From: liqigan Date: Wed, 14 Aug 2024 19:42:09 +0800 Subject: [PATCH] feat(bt/bluedroid): Add API to create Device ID Service record --- components/bt/common/btc/core/btc_task.c | 14 +- components/bt/host/bluedroid/Kconfig.in | 9 +- .../bt/host/bluedroid/api/esp_sdp_api.c | 43 +- .../bluedroid/api/include/api/esp_sdp_api.h | 201 ++++---- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 56 ++- .../bluedroid/bta/dm/include/bta_dm_int.h | 1 + .../host/bluedroid/bta/include/bta/bta_api.h | 11 + .../bluedroid/bta/include/bta/bta_sdp_api.h | 27 +- .../bt/host/bluedroid/bta/sdp/bta_sdp.c | 9 +- .../bt/host/bluedroid/bta/sdp/bta_sdp_act.c | 72 ++- .../bt/host/bluedroid/bta/sdp/bta_sdp_api.c | 14 +- .../bluedroid/bta/sdp/include/bta_sdp_int.h | 2 + .../btc/profile/std/include/bt_sdp.h | 92 ++-- .../btc/profile/std/include/btc_sdp.h | 10 +- .../bluedroid/btc/profile/std/sdp/btc_sdp.c | 434 +++++++++++------- .../include/common/bluedroid_user_config.h | 15 +- .../common/include/common/bt_target.h | 7 +- .../bt/host/bluedroid/stack/sdp/sdp_db.c | 40 +- .../release-5.x/5.4/bluetooth-classic.rst | 16 + .../release-5.x/5.4/index.rst | 1 + .../release-5.x/5.4/bluetooth-classic.rst | 16 + .../release-5.x/5.4/index.rst | 1 + .../classic_bt/bt_l2cap_client/main/main.c | 10 +- .../bt_l2cap_client/sdkconfig.defaults | 1 + .../classic_bt/bt_l2cap_server/main/main.c | 10 +- .../bt_l2cap_server/sdkconfig.defaults | 1 + 26 files changed, 746 insertions(+), 367 deletions(-) create mode 100644 docs/en/migration-guides/release-5.x/5.4/bluetooth-classic.rst create mode 100644 docs/zh_CN/migration-guides/release-5.x/5.4/bluetooth-classic.rst diff --git a/components/bt/common/btc/core/btc_task.c b/components/bt/common/btc/core/btc_task.c index 0f2b6bc0b7..875f64b18a 100644 --- a/components/bt/common/btc/core/btc_task.c +++ b/components/bt/common/btc/core/btc_task.c @@ -42,9 +42,9 @@ #if (BTC_L2CAP_INCLUDED == TRUE) #include "btc_l2cap.h" #endif /* #if (BTC_L2CAP_INCLUDED == TRUE) */ -#if (BTC_SDP_INCLUDED == TRUE) +#if (BTC_SDP_COMMON_INCLUDED == TRUE) #include "btc_sdp.h" -#endif /* #if (BTC_SDP_INCLUDED == TRUE) */ +#endif /* #if (BTC_SDP_COMMON_INCLUDED == TRUE) */ #if BTC_HF_INCLUDED #include "btc_hf_ag.h" #endif/* #if BTC_HF_INCLUDED */ @@ -138,9 +138,9 @@ static const btc_func_t profile_tab[BTC_PID_NUM] = { #if (BTC_L2CAP_INCLUDED == TRUE) [BTC_PID_L2CAP] = {btc_l2cap_call_handler, btc_l2cap_cb_handler }, #endif /* #if (BTC_L2CAP_INCLUDED == TRUE) */ -#if (BTC_SDP_INCLUDED == TRUE) +#if (BTC_SDP_COMMON_INCLUDED == TRUE) [BTC_PID_SDP] = {btc_sdp_call_handler, btc_sdp_cb_handler }, -#endif /* #if (BTC_SDP_INCLUDED == TRUE) */ +#endif /* #if (BTC_SDP_COMMON_INCLUDED == TRUE) */ #if BTC_HF_INCLUDED [BTC_PID_HF] = {btc_hf_call_handler, btc_hf_cb_handler}, #endif /* #if BTC_HF_INCLUDED */ @@ -295,8 +295,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 @@ -342,7 +342,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/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 16985a7dff..4271b47869 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -102,6 +102,13 @@ config BT_L2CAP_ENABLED This enables the Logical Link Control and Adaptation Layer Protocol. Only supported classic bluetooth. +config BT_SDP_COMMON_ENABLED + bool "BT SDP COMMON" + depends on BT_CLASSIC_ENABLED + default n + help + This enables common SDP operation, such as SDP record creation and deletion. + menuconfig BT_HFP_ENABLE bool "Hands Free/Handset Profile" depends on BT_CLASSIC_ENABLED @@ -148,7 +155,7 @@ menuconfig BT_HID_ENABLED depends on BT_CLASSIC_ENABLED default n help - This enables the BT HID Host + This enables the BT HID functionalities config BT_HID_HOST_ENABLED bool "Classic BT HID Host" diff --git a/components/bt/host/bluedroid/api/esp_sdp_api.c b/components/bt/host/bluedroid/api/esp_sdp_api.c index c47c5ba50a..1cae445260 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 */ @@ -8,12 +8,43 @@ #include "esp_bt_main.h" #include "btc/btc_manage.h" +#include "stack/sdpdefs.h" #include "btc_sdp.h" #include "esp_sdp_api.h" #include "common/bt_target.h" -#if (defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE) +#if (defined BTC_SDP_COMMON_INCLUDED && BTC_SDP_COMMON_INCLUDED == TRUE) + +static bool esp_sdp_record_integrity_check(esp_bluetooth_sdp_record_t *record) +{ + bool ret = true; + + if (record != NULL) { + switch (record->hdr.type) { + case ESP_SDP_TYPE_DIP_SERVER: + if (record->dip.vendor_id_source != ESP_SDP_VENDOR_ID_SRC_BT && + record->dip.vendor_id_source != ESP_SDP_VENDOR_ID_SRC_USB) { + LOG_ERROR("Invalid vendor_id_source!\n"); + ret = false; + } + break; + + default: + 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; + } + break; + } + } else { + LOG_ERROR("record is NULL!\n"); + ret = false; + } + + return ret; +} esp_err_t esp_sdp_register_callback(esp_sdp_cb_t callback) { @@ -85,9 +116,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 +129,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), @@ -127,4 +156,4 @@ esp_err_t esp_sdp_remove_record(int record_handle) return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; } -#endif ///defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE +#endif ///defined BTC_SDP_COMMON_INCLUDED && BTC_SDP_COMMON_INCLUDED == TRUE 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 14741e7471..99bf61be3f 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,163 @@ 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_SDP_TYPE_DIP_SERVER, /*!< Device Identification 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 */ +typedef struct { + esp_bluetooth_sdp_types_t type; /*!< SDP type */ + 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 */ +} esp_bluetooth_sdp_hdr_t; - // 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_hdr_overlay_t; +/** + * @brief Raw SDP record + */ +typedef struct { + esp_bluetooth_sdp_hdr_t hdr; /*!< General info */ + esp_bt_uuid_t uuid; /*!< UUID type, include uuid and uuid length */ + int user1_ptr_len; /*!< Length of raw SDP data */ + uint8_t *user1_ptr; /*!< Raw SDP data */ +} esp_bluetooth_sdp_raw_record_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 */ +typedef struct { + esp_bluetooth_sdp_hdr_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 */ +typedef struct { + esp_bluetooth_sdp_hdr_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 */ +typedef struct { + esp_bluetooth_sdp_hdr_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 */ +typedef struct { + esp_bluetooth_sdp_hdr_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 */ +typedef struct { + esp_bluetooth_sdp_hdr_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 */ +typedef struct { + esp_bluetooth_sdp_hdr_t hdr; /*!< General info */ } esp_bluetooth_sdp_sap_record_t; +/** + * @brief Vendor ID source + */ +typedef enum { + ESP_SDP_VENDOR_ID_SRC_BT = 1, /*!< Bluetooth assigned vendor id source */ + ESP_SDP_VENDOR_ID_SRC_USB = 2, /*!< USB assigned vendor id source */ +} esp_sdp_vendor_id_source_t; + +/** + * @brief Device Identification Profile parameters + * + * @note Only one primary Device Identification service record can be added in the SDP database. If primary + * Device Identification service is created multiple times, only the last one will take effect. + */ +typedef struct { + esp_bluetooth_sdp_hdr_t hdr; /*!< General info */ + uint16_t vendor; /*!< Vendor ID */ + uint16_t vendor_id_source; /*!< Vendor ID source, 0x0001 for Bluetooth, 0x0002 for USB, other values reserved, see `esp_sdp_vendor_id_source_t` */ + uint16_t product; /*!< Product ID */ + uint16_t version; /*!< Release version in format 0xJJMN(JJ – major number, M – minor number, N – sub-minor number) */ + bool primary_record; /*!< Indicate if the record is primary, shall set to true if there is a only single device + record, others shall be set to false */ +} esp_bluetooth_sdp_dip_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_t hdr; /*!< General info */ + esp_bluetooth_sdp_raw_record_t raw; /*!< Raw SDP search data for unknown UUIDs */ + 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_dip_record_t dip; /*!< Device Identification Profile */ } esp_bluetooth_sdp_record_t; /** @@ -141,44 +181,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 */ + 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 a2282cd9bc..7ec61ee999 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" @@ -1086,22 +1087,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 f8548edea4..862393fe8a 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 @@ -1590,6 +1590,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 75a8199459..8b0f40de18 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -2190,6 +2190,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 62b5228a88..f49c76c4e5 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 */ @@ -108,14 +115,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 4deabe9aff..71773d984c 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 8427a6ce23..2ece2df56d 100644 --- a/components/bt/host/bluedroid/bta/sdp/bta_sdp_act.c +++ b/components/bt/host/bluedroid/bta/sdp/bta_sdp_act.c @@ -140,6 +140,47 @@ static void bta_create_mns_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_RE } } +static void bta_create_dip_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec) +{ + tSDP_DISC_ATTR *p_attr; + UINT16 pversion = -1; + + record->dip.hdr.type = SDP_TYPE_DIP_SERVER; + record->dip.hdr.service_name_length = 0; + record->dip.hdr.service_name = NULL; + record->dip.hdr.rfcomm_channel_number = 0; + record->dip.hdr.l2cap_psm = -1; + record->dip.hdr.profile_version = 0; + + p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_VENDOR_ID); + if (p_attr) { + record->dip.vendor = p_attr->attr_value.v.u16; + } + + p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_VENDOR_ID_SOURCE); + if (p_attr) { + record->dip.vendor_id_source = p_attr->attr_value.v.u16; + } + p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PRODUCT_ID); + if (p_attr) { + record->dip.product = p_attr->attr_value.v.u16; + } + + p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PRODUCT_VERSION); + if (p_attr) { + record->dip.version = p_attr->attr_value.v.u16; + } + + p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PRIMARY_RECORD); + if (p_attr) { + record->dip.primary_record = (BOOLEAN)p_attr->attr_value.v.u8; + } + + if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_PNP_INFORMATION, &pversion)) { + record->dip.hdr.profile_version = pversion; + } +} + static void bta_create_mas_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec) { tSDP_DISC_ATTR *p_attr; @@ -375,8 +416,8 @@ static void bta_create_raw_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_RE if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) { record->pse.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 = p_bta_sdp_cfg->p_sdp_db->raw_data; + record->raw.user1_ptr_len = p_bta_sdp_cfg->p_sdp_db->raw_size; + record->raw.user1_ptr = p_bta_sdp_cfg->p_sdp_db->raw_data; } @@ -415,7 +456,10 @@ static void bta_sdp_search_cback(UINT16 result, void *user_data) /* generate the matching record data pointer */ if (p_rec != NULL) { status = BTA_SDP_SUCCESS; - if (IS_UUID(UUID_MAP_MAS, uuid->uu.uuid128)) { + if (uuid->uu.uuid16 == UUID_SERVCLASS_PNP_INFORMATION) { + APPL_TRACE_DEBUG("%s() - found DIP uuid\n", __func__); + bta_create_dip_sdp_record(&evt_data.records[count], p_rec); + } else if (IS_UUID(UUID_MAP_MAS, uuid->uu.uuid128)) { APPL_TRACE_DEBUG("%s() - found MAP (MAS) uuid\n", __func__); bta_create_mas_sdp_record(&evt_data.records[count], p_rec); } else if (IS_UUID(UUID_MAP_MNS, uuid->uu.uuid128)) { @@ -576,10 +620,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 cafb1a4a4c..86fb61ca41 100644 --- a/components/bt/host/bluedroid/bta/sdp/bta_sdp_api.c +++ b/components/bt/host/bluedroid/bta/sdp/bta_sdp_api.c @@ -101,15 +101,27 @@ 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; #endif - return (status); + return BTA_SDP_SUCCESS; } /******************************************************************************* 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 cf0eb99cc1..f350ae372f 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 63ca09a80f..5c7202a7ae 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,79 +34,77 @@ 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 + SDP_TYPE_DIP_SERVER, // Device Identification 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; + 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; -} bluetooth_sdp_hdr_overlay; +typedef struct _bluetooth_sdp_raw_record { + bluetooth_sdp_hdr hdr; + esp_bt_uuid_t uuid; + int user1_ptr_len; + uint8_t *user1_ptr; +} bluetooth_sdp_raw_record; 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; + bluetooth_sdp_hdr hdr; + 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; + bluetooth_sdp_hdr hdr; + 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; + bluetooth_sdp_hdr hdr; + uint32_t supported_features; + uint32_t supported_repositories; } bluetooth_sdp_pse_record; typedef struct _bluetooth_sdp_pce_record { - bluetooth_sdp_hdr_overlay hdr; + bluetooth_sdp_hdr hdr; } 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]; + bluetooth_sdp_hdr hdr; + 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 { - bluetooth_sdp_hdr_overlay hdr; + bluetooth_sdp_hdr hdr; } bluetooth_sdp_sap_record; +typedef struct _bluetooth_sdp_dip_record { + bluetooth_sdp_hdr hdr; + uint16_t vendor; + uint16_t vendor_id_source; + uint16_t product; + uint16_t version; + bool primary_record; +} bluetooth_sdp_dip_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 hdr; + bluetooth_sdp_raw_record raw; + 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_dip_record dip; } 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 60772fa3c4..2f5aad95f9 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 */ @@ -13,7 +13,7 @@ #include "bta/bta_sdp_api.h" #include "bt_sdp.h" -#if (defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE) +#if (defined BTC_SDP_COMMON_INCLUDED && BTC_SDP_COMMON_INCLUDED == TRUE) typedef enum { BTC_SDP_ACT_INIT = 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 { @@ -49,5 +49,5 @@ void btc_sdp_arg_deep_free(btc_msg_t *msg); void btc_sdp_call_handler(btc_msg_t *msg); void btc_sdp_cb_handler(btc_msg_t *msg); -#endif ///defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE +#endif ///defined BTC_SDP_COMMON_INCLUDED && BTC_SDP_COMMON_INCLUDED == TRUE #endif ///__BTC_SDP_H__ 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 544b661b4a..f395757c7d 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 @@ -17,7 +17,7 @@ #include "osi/allocator.h" #include "esp_sdp_api.h" -#if (defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE) +#if (defined BTC_SDP_COMMON_INCLUDED && BTC_SDP_COMMON_INCLUDED == TRUE) typedef enum { SDP_RECORD_FREE = 0, @@ -25,10 +25,17 @@ typedef enum { } sdp_state_t; typedef struct { - sdp_state_t state; + uint8_t di : 1; + uint8_t primary_di : 1; + uint8_t reserved : 6; +} sdp_flag_t; + +typedef struct { + uint8_t state; + sdp_flag_t flag; int sdp_handle; esp_bt_uuid_t uuid; - bluetooth_sdp_record* record_data; + void* record_data; } sdp_slot_t; typedef struct { @@ -56,7 +63,7 @@ static void btc_sdp_cleanup(void) if (sdp_local_param_ptr) { #endif if (sdp_local_param.sdp_slot_mutex) { - osi_mutex_free(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 @@ -74,36 +81,28 @@ static inline void btc_sdp_cb_to_app(esp_sdp_cb_event_t event, esp_sdp_cb_param_ } } -static void sdp_disable_handler(void) +static int get_sdp_record_size(bluetooth_sdp_record* in_record) { - 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) -{ - 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]; + switch (record->hdr.type) { + case SDP_TYPE_DIP_SERVER: + records_size = sizeof(bluetooth_sdp_record); + break; + + case SDP_TYPE_RAW: + if (record->raw.user1_ptr != NULL) { + records_size += record->raw.user1_ptr_len; + } + /* fall through */ + default: records_size += sizeof(bluetooth_sdp_record); records_size += record->hdr.service_name_length; - if(record->hdr.service_name_length > 0){ + 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; + break; } return records_size; @@ -136,32 +135,53 @@ static void set_sdp_slot_info(int id, int sdp_handle, esp_bt_uuid_t *uuid) } slot->sdp_handle = sdp_handle; slot->record_data = NULL; - memcpy(&slot->uuid, uuid, sizeof(esp_bt_uuid_t)); + 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_uuid_by_handle(int handle, esp_bt_uuid_t **uuid) +static void get_sdp_slot_info(int id, int *sdp_handle, esp_bt_uuid_t *uuid, sdp_flag_t *flag) { - bool ret = false; 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)) { - if (uuid) { - *uuid = &slot->uuid; - } - ret = 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)); + } + + if (flag) { + *flag = slot->flag; + } + } while (0); osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); - return ret; } static int get_sdp_slot_id_by_handle(int handle) @@ -217,47 +237,70 @@ static bluetooth_sdp_record *start_create_sdp(int id) /* 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 */ + uint8_t *free_ptr = (uint8_t *)(out_record + 1); /* 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; + 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 = 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; - } + 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++; } + + if (in_record->hdr.type == SDP_TYPE_RAW && in_record->raw.user1_ptr != NULL) { + out_record->raw.user1_ptr = (UINT8 *)free_ptr; // Update pointer + memcpy(free_ptr, in_record->raw.user1_ptr, in_record->raw.user1_ptr_len); // Copy content + free_ptr += in_record->raw.user1_ptr_len; + } +} + +static void copy_sdp_record(bluetooth_sdp_record* in_record, bluetooth_sdp_record* out_record) +{ + switch (in_record->hdr.type) { + case SDP_TYPE_DIP_SERVER: + memcpy(out_record, in_record, sizeof(bluetooth_sdp_record)); + break; + + default: + copy_sdp_record_common(in_record, out_record); + break; + } +} + +static bool check_if_primary_di_record(bluetooth_sdp_record* record) +{ + bool ret = false; + + if (record->hdr.type == SDP_TYPE_DIP_SERVER) { + bluetooth_sdp_dip_record *di_record = (bluetooth_sdp_dip_record *)record; + ret = di_record->primary_record; + } + + return ret; +} + +static bool check_if_di_record(bluetooth_sdp_record* record) +{ + return record->hdr.type == SDP_TYPE_DIP_SERVER ? true : false; } 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; + bool is_di_record = check_if_di_record(in_record); + bool is_primary_di_record = check_if_primary_di_record(in_record); + bool primary_di_record_found = false; record = osi_malloc(record_size); if (record == NULL) { @@ -265,22 +308,42 @@ 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++) - { - slot = &sdp_local_param.sdp_slots[i]; - if ((*slot) == NULL) { - if (((*slot) = (sdp_slot_t *)osi_malloc(sizeof(sdp_slot_t))) == NULL) { - osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); - BTC_TRACE_ERROR("%s() osi_malloc slot failed!", __func__); - osi_free(record); - return -1; + // find the primary di record slot + if (is_di_record && is_primary_di_record) { + for (i = 0; i < SDP_MAX_RECORDS; i++) { + slot = &sdp_local_param.sdp_slots[i]; + if ((*slot) && (*slot)->flag.di && (*slot)->flag.primary_di) { + BTC_TRACE_WARNING("%s() overwrite primary di record!", __func__); + if ((*slot)->record_data) { + osi_free((*slot)->record_data); + } + + (*slot)->record_data = record; + primary_di_record_found = true; + break; + } + } + } + + if (!primary_di_record_found) { + 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) { + osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); + BTC_TRACE_ERROR("%s() osi_malloc slot failed!", __func__); + osi_free(record); + return -1; + } + (*slot)->flag.di = is_di_record; + (*slot)->flag.primary_di = is_primary_di_record; + (*slot)->state = SDP_RECORD_ALLOCED; + (*slot)->record_data = record; + break; } - (*slot)->state = SDP_RECORD_ALLOCED; - (*slot)->record_data = record; - break; } } osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); @@ -330,7 +393,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_raw_record *rec) { tSDP_PROTOCOL_ELEM protoList [2]; UINT16 browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP; @@ -348,15 +411,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 (rec->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, rec->uuid.uuid.uuid16); + } else if (rec->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, rec->uuid.uuid.uuid32); + } else if (rec->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, rec->uuid.uuid.uuid128, LEN_UUID_128); } else { SDP_DeleteRecord(sdp_handle); sdp_handle = 0; @@ -403,12 +466,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 (rec->uuid.len == ESP_UUID_LEN_16) { + bta_sys_add_uuid(rec->uuid.uuid.uuid16); + } else if (rec->uuid.len == ESP_UUID_LEN_32) { + bta_sys_add_uuid_32(rec->uuid.uuid.uuid32); + } else if (rec->uuid.len == ESP_UUID_LEN_128) { + bta_sys_add_uuid_128((UINT8 *)&rec->uuid.uuid.uuid128); } BTC_TRACE_DEBUG("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle); } @@ -852,35 +915,68 @@ static int add_saps_sdp(const bluetooth_sdp_sap_record* rec) return sdp_handle; } +static int add_dips_sdp(bluetooth_sdp_dip_record *rec) +{ + UINT32 sdp_handle = 0; + tBTA_DI_RECORD device_info = {0}; + + device_info.vendor = rec->vendor; + device_info.vendor_id_source = rec->vendor_id_source; + device_info.product = rec->product; + device_info.version = rec->version; + device_info.primary_record = rec->primary_record; + + BTA_DmSetLocalDiRecord(&device_info, &sdp_handle); + + return sdp_handle; +} + static int btc_handle_create_record_event(int id) { 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__); - bluetooth_sdp_record *record = start_create_sdp(id); - if(record != NULL) { + if (record != NULL) { switch (record->hdr.type) { case SDP_TYPE_RAW: - sdp_handle = add_raw_sdp(record); + sdp_handle = add_raw_sdp(&record->raw); + memcpy(&service_uuid, &record->raw.uuid, sizeof(esp_bt_uuid_t)); break; case SDP_TYPE_MAP_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: 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: 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: 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: 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: sdp_handle = add_saps_sdp(&record->sap); + service_uuid.len = ESP_UUID_LEN_16; + service_uuid.uuid.uuid16 = UUID_SERVCLASS_SAP; + break; + case SDP_TYPE_DIP_SERVER: + sdp_handle = add_dips_sdp(&record->dip); break; default: BTC_TRACE_DEBUG("Record type %d is not supported", record->hdr.type); @@ -888,7 +984,7 @@ static int btc_handle_create_record_event(int id) } if(sdp_handle != 0) { - set_sdp_slot_info(id, sdp_handle, &record->hdr.bt_uuid); + set_sdp_slot_info(id, sdp_handle, &service_uuid); // free the record, since not use it anymore osi_free(record); } else { @@ -905,16 +1001,40 @@ static int btc_handle_create_record_event(int 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) { - bool result = false; - BTC_TRACE_DEBUG("Sdp Server %s", __func__); - if(handle != -1 && handle != 0) { - result = SDP_DeleteRecord(handle); - if(result == false) { - BTC_TRACE_ERROR(" Unable to remove handle 0x%08x", handle); + bool result = false; + int sdp_handle = -1; + sdp_flag_t flag = {0}; + esp_bt_uuid_t service_uuid = {0}; + + get_sdp_slot_info(id, &sdp_handle, &service_uuid, &flag); + + if (sdp_handle > 0) { + if (flag.di && BTA_DmRemoveLocalDiRecord(sdp_handle) == BTA_SUCCESS) { + result = true; + } else { + 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; } } @@ -928,18 +1048,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; } } } @@ -1007,7 +1127,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()) { @@ -1017,12 +1136,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, NULL); + if (sdp_handle > 0) { + BTA_SdpRemoveRecordByUser((void*)i); } } - sdp_disable_handler(); + BTA_SdpDisable(); } while(0); if (ret != ESP_SDP_SUCCESS) { @@ -1033,7 +1153,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; @@ -1044,13 +1164,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) { @@ -1062,7 +1182,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; @@ -1073,42 +1192,16 @@ static void btc_sdp_remove_record(btc_sdp_args_t *arg) break; } - esp_bt_uuid_t *service_uuid = NULL; - if (get_sdp_uuid_by_handle(arg->remove_record.record_handle, &service_uuid)) { - 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); - } - } 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) { @@ -1151,25 +1244,20 @@ 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; + 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; 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)); + 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; @@ -1179,14 +1267,12 @@ 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; + bluetooth_sdp_record *record = arg->create_record.record; 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); + if (record) { + osi_free(record); } break; default: @@ -1269,7 +1355,17 @@ 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: @@ -1278,4 +1374,4 @@ void btc_sdp_cb_handler(btc_msg_t *msg) } } -#endif ///defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE +#endif ///defined BTC_SDP_COMMON_INCLUDED && BTC_SDP_COMMON_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 15d2c55f09..c92d7de2b0 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,23 @@ //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 + +//SDP common +#ifdef CONFIG_BT_SDP_COMMON_ENABLED +#define UC_BT_SDP_COMMON_ENABLED CONFIG_BT_SDP_COMMON_ENABLED +#else +#define UC_BT_SDP_COMMON_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/common/include/common/bt_target.h b/components/bt/host/bluedroid/common/include/common/bt_target.h index a18c7aadb1..4227ef38e9 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -103,10 +103,13 @@ #if (UC_BT_L2CAP_ENABLED == TRUE) #define BTA_JV_INCLUDED TRUE #define BTC_L2CAP_INCLUDED TRUE -#define BTC_SDP_INCLUDED TRUE #define VND_BT_JV_BTA_L2CAP TRUE #endif /* UC_BT_L2CAP_ENABLED */ +#if (UC_BT_SDP_COMMON_ENABLED == TRUE) +#define BTC_SDP_COMMON_INCLUDED TRUE +#endif /* UC_BT_SDP_COMMON_ENABLED */ + #if (UC_BT_HFP_AG_ENABLED == TRUE) || (UC_BT_HFP_CLIENT_ENABLED == TRUE) #ifndef RFCOMM_INCLUDED #define RFCOMM_INCLUDED TRUE @@ -1500,7 +1503,7 @@ /* The maximum number of attributes in each record. */ #ifndef SDP_MAX_REC_ATTR -#if (defined(HID_DEV_INCLUDED) && (HID_DEV_INCLUDED==TRUE)) || (defined(BTC_SDP_INCLUDED) && (BTC_SDP_INCLUDED==TRUE)) +#if (defined(HID_DEV_INCLUDED) && (HID_DEV_INCLUDED==TRUE)) || (defined(BTC_SDP_COMMON_INCLUDED) && (BTC_SDP_COMMON_INCLUDED==TRUE)) #define SDP_MAX_REC_ATTR 25 #else #define SDP_MAX_REC_ATTR 8 diff --git a/components/bt/host/bluedroid/stack/sdp/sdp_db.c b/components/bt/host/bluedroid/stack/sdp/sdp_db.c index a9b3daa4ca..60dd04a6b9 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; } diff --git a/docs/en/migration-guides/release-5.x/5.4/bluetooth-classic.rst b/docs/en/migration-guides/release-5.x/5.4/bluetooth-classic.rst new file mode 100644 index 0000000000..2c229ad4a2 --- /dev/null +++ b/docs/en/migration-guides/release-5.x/5.4/bluetooth-classic.rst @@ -0,0 +1,16 @@ +Bluetooth Classic +================= + +:link_to_translation:`zh_CN:[中文]` + +Bluedroid +--------- + +- Previously, the use of SDP APIs was affected by the ``CONFIG_BT_L2CAP_ENABLED`` configuration, although there was no relationship between them. The new Kconfig option ``CONFIG_BT_SDP_COMMON_ENABLED`` has been introduced to separate common SDP operations from Classic Bluetooth L2CAP functionality. It shall be enabled before calling SDP related APIs. +- The following Bluedroid API have been changed: + + - :component_file:`/bt/host/bluedroid/api/include/api/esp_sdp_api.h` + + - structure ``esp_bluetooth_sdp_hdr_overlay_t`` has been renamed to ``esp_bluetooth_sdp_hdr_t`` + - field ``uuid``, ``user1_ptr_len`` and ``user1_ptr`` in ``esp_bluetooth_sdp_hdr_overlay_t`` have been moved into ``esp_bluetooth_sdp_raw_record_t`` + - field ``user2_ptr_len`` and ``user2_ptr`` in ``esp_bluetooth_sdp_hdr_overlay_t`` have been removed diff --git a/docs/en/migration-guides/release-5.x/5.4/index.rst b/docs/en/migration-guides/release-5.x/5.4/index.rst index 811e692e34..3735b0cd5b 100644 --- a/docs/en/migration-guides/release-5.x/5.4/index.rst +++ b/docs/en/migration-guides/release-5.x/5.4/index.rst @@ -7,3 +7,4 @@ Migration from 5.3 to 5.4 :maxdepth: 1 system + bluetooth-classic diff --git a/docs/zh_CN/migration-guides/release-5.x/5.4/bluetooth-classic.rst b/docs/zh_CN/migration-guides/release-5.x/5.4/bluetooth-classic.rst new file mode 100644 index 0000000000..b911fc11c5 --- /dev/null +++ b/docs/zh_CN/migration-guides/release-5.x/5.4/bluetooth-classic.rst @@ -0,0 +1,16 @@ +经典蓝牙 +================= + +:link_to_translation:`en:[English]` + +Bluedroid +--------- + +- 之前,SDP 相关 API 的使用受到配置项 ``CONFIG_BT_L2CAP_ENABLED`` 影响,但是这两者并没有太大关联。新的配置项 ``CONFIG_BT_SDP_COMMON_ENABLED`` 将 SDP 通用功能从经典蓝牙 L2CAP 功能中分离出来,在使用 SDP 相关 API 前需要先使能该配置项。 +- 以下 Bluedroid API 发生变更 + + - :component_file:`/bt/host/bluedroid/api/include/api/esp_sdp_api.h` + + - 结构体 ``esp_bluetooth_sdp_hdr_overlay_t`` 被重命名为 ``esp_bluetooth_sdp_hdr_t`` + - 结构体 ``esp_bluetooth_sdp_hdr_overlay_t`` 中的字段 ``uuid``, ``user1_ptr_len`` 和 ``user1_ptr`` 被移动到结构体 ``esp_bluetooth_sdp_raw_record_t`` 中 + - 结构体 ``esp_bluetooth_sdp_hdr_overlay_t`` 中的字段 ``user2_ptr_len`` 和 ``user2_ptr`` 被删除 diff --git a/docs/zh_CN/migration-guides/release-5.x/5.4/index.rst b/docs/zh_CN/migration-guides/release-5.x/5.4/index.rst index c5ec458a4f..8135624310 100644 --- a/docs/zh_CN/migration-guides/release-5.x/5.4/index.rst +++ b/docs/zh_CN/migration-guides/release-5.x/5.4/index.rst @@ -7,3 +7,4 @@ :maxdepth: 1 system + bluetooth-classic diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/main/main.c b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/main/main.c index 37fda38a61..e24684d978 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/main/main.c @@ -331,7 +331,7 @@ static void esp_sdp_cb(esp_sdp_cb_event_t event, esp_sdp_cb_param_t *param) static void esp_hdl_sdp_cb_evt(uint16_t event, void *p_param) { - esp_bluetooth_sdp_record_t record = {0}; + esp_bluetooth_sdp_raw_record_t record = {0}; esp_sdp_cb_param_t *sdp_param = (esp_sdp_cb_param_t *)p_param; char bda_str[18] = {0}; @@ -340,14 +340,16 @@ static void esp_hdl_sdp_cb_evt(uint16_t event, void *p_param) ESP_LOGI(SDP_TAG, "ESP_SDP_INIT_EVT: status:%d", sdp_param->init.status); if (sdp_param->init.status == ESP_SDP_SUCCESS) { record.hdr.type = ESP_SDP_TYPE_RAW; - record.hdr.uuid.len = sizeof(UUID_UNKNOWN); - memcpy(record.hdr.uuid.uuid.uuid128, UUID_UNKNOWN, sizeof(UUID_UNKNOWN)); record.hdr.service_name_length = strlen(sdp_service_name) + 1; record.hdr.service_name = sdp_service_name; record.hdr.rfcomm_channel_number = BT_UNUSED_RFCOMM; record.hdr.l2cap_psm = BT_L2CAP_DYNMIC_PSM; record.hdr.profile_version = BT_UNKONWN_PROFILE_VERSION; - esp_sdp_create_record(&record); + record.uuid.len = sizeof(UUID_UNKNOWN); + memcpy(record.uuid.uuid.uuid128, UUID_UNKNOWN, sizeof(UUID_UNKNOWN)); + record.user1_ptr = NULL; + record.user1_ptr_len = 0; + esp_sdp_create_record((esp_bluetooth_sdp_record_t *)&record); } break; case ESP_SDP_DEINIT_EVT: diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/sdkconfig.defaults index 8fd8809a41..0ea21ae781 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/sdkconfig.defaults @@ -7,3 +7,4 @@ CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_BLUEDROID_ENABLED=y CONFIG_BT_CLASSIC_ENABLED=y CONFIG_BT_L2CAP_ENABLED=y +CONFIG_BT_SDP_COMMON_ENABLED=y diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/main/main.c b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/main/main.c index 98feadc71d..254f381834 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/main/main.c @@ -242,7 +242,7 @@ static void esp_sdp_cb(esp_sdp_cb_event_t event, esp_sdp_cb_param_t *param) static void esp_hdl_sdp_cb_evt(uint16_t event, void *p_param) { - esp_bluetooth_sdp_record_t record = {0}; + esp_bluetooth_sdp_raw_record_t record = {0}; esp_sdp_cb_param_t *sdp_param = (esp_sdp_cb_param_t *)p_param; switch (event) { @@ -250,14 +250,16 @@ static void esp_hdl_sdp_cb_evt(uint16_t event, void *p_param) ESP_LOGI(SDP_TAG, "ESP_SDP_INIT_EVT: status:%d", sdp_param->init.status); if (sdp_param->init.status == ESP_SDP_SUCCESS) { record.hdr.type = ESP_SDP_TYPE_RAW; - record.hdr.uuid.len = sizeof(UUID_UNKNOWN); - memcpy(record.hdr.uuid.uuid.uuid128, UUID_UNKNOWN, sizeof(UUID_UNKNOWN)); record.hdr.service_name_length = strlen(sdp_service_name) + 1; record.hdr.service_name = sdp_service_name; record.hdr.rfcomm_channel_number = BT_UNUSED_RFCOMM; record.hdr.l2cap_psm = BT_L2CAP_DYNMIC_PSM; record.hdr.profile_version = BT_UNKONWN_PROFILE_VERSION; - esp_sdp_create_record(&record); + record.uuid.len = sizeof(UUID_UNKNOWN); + memcpy(record.uuid.uuid.uuid128, UUID_UNKNOWN, sizeof(UUID_UNKNOWN)); + record.user1_ptr = NULL; + record.user1_ptr_len = 0; + esp_sdp_create_record((esp_bluetooth_sdp_record_t *)&record); } break; case ESP_SDP_DEINIT_EVT: diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/sdkconfig.defaults index 8fd8809a41..0ea21ae781 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/sdkconfig.defaults @@ -7,3 +7,4 @@ CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_BLUEDROID_ENABLED=y CONFIG_BT_CLASSIC_ENABLED=y CONFIG_BT_L2CAP_ENABLED=y +CONFIG_BT_SDP_COMMON_ENABLED=y