xiongweichao преди 3 години
родител
ревизия
1d9fd4707a

+ 2 - 0
components/bt/CMakeLists.txt

@@ -113,6 +113,7 @@ if(CONFIG_BT_ENABLED)
                    "host/bluedroid/api/esp_hf_ag_api.c"
                    "host/bluedroid/api/esp_hf_client_api.c"
                    "host/bluedroid/api/esp_spp_api.c"
+                   "host/bluedroid/api/esp_sdp_api.c"
                    "host/bluedroid/api/esp_l2cap_bt_api.c"
                    "host/bluedroid/bta/ar/bta_ar.c"
                    "host/bluedroid/bta/av/bta_av_aact.c"
@@ -215,6 +216,7 @@ if(CONFIG_BT_ENABLED)
                    "host/bluedroid/btc/profile/std/gatt/btc_gattc.c"
                    "host/bluedroid/btc/profile/std/gatt/btc_gatts.c"
                    "host/bluedroid/btc/profile/std/spp/btc_spp.c"
+                   "host/bluedroid/btc/profile/std/sdp/btc_sdp.c"
                    "host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c"
                    "host/bluedroid/device/bdaddr.c"
                    "host/bluedroid/device/controller.c"

+ 6 - 0
components/bt/common/btc/core/btc_task.c

@@ -42,6 +42,9 @@
 #if (BTC_L2CAP_INCLUDED == TRUE)
 #include "btc_l2cap.h"
 #endif /* #if (BTC_L2CAP_INCLUDED == TRUE) */
+#if (BTC_SDP_INCLUDED == TRUE)
+#include "btc_sdp.h"
+#endif /* #if (BTC_SDP_INCLUDED == TRUE) */
 #if BTC_HF_INCLUDED
 #include "btc_hf_ag.h"
 #endif/* #if BTC_HF_INCLUDED */
@@ -118,6 +121,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)
+    [BTC_PID_SDP]       = {btc_sdp_call_handler,          btc_sdp_cb_handler      },
+#endif /* #if (BTC_SDP_INCLUDED == TRUE) */
 #if BTC_HF_INCLUDED
     [BTC_PID_HF]   = {btc_hf_call_handler,  btc_hf_cb_handler},
 #endif  /* #if BTC_HF_INCLUDED */

+ 1 - 0
components/bt/common/btc/include/btc/btc_task.h

@@ -60,6 +60,7 @@ typedef enum {
     BTC_PID_HD,
     BTC_PID_HH,
     BTC_PID_L2CAP,
+    BTC_PID_SDP,
 #if (BTC_HF_INCLUDED == TRUE)
     BTC_PID_HF,
 #endif /* BTC_HF_INCLUDED */

+ 129 - 0
components/bt/host/bluedroid/api/esp_sdp_api.c

@@ -0,0 +1,129 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <string.h>
+
+#include "esp_bt_main.h"
+#include "btc/btc_manage.h"
+
+#include "btc_sdp.h"
+#include "esp_sdp_api.h"
+#include "common/bt_target.h"
+
+#if (defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE)
+
+esp_err_t esp_sdp_register_callback(esp_sdp_cb_t callback)
+{
+    ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+
+    if (callback == NULL) {
+        return ESP_FAIL;
+    }
+
+    btc_profile_cb_set(BTC_PID_SDP, callback);
+    return ESP_OK;
+}
+
+esp_err_t esp_sdp_init(void)
+{
+    ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+
+    btc_msg_t msg;
+    bt_status_t stat;
+
+    msg.sig = BTC_SIG_API_CALL;
+    msg.pid = BTC_PID_SDP;
+    msg.act = BTC_SDP_ACT_INIT;
+
+    /* Switch to BTC context */
+    stat = btc_transfer_context(&msg, NULL, 0, NULL);
+    return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
+}
+
+esp_err_t esp_sdp_deinit(void)
+{
+    ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+
+    btc_msg_t msg;
+    bt_status_t stat;
+
+    msg.sig = BTC_SIG_API_CALL;
+    msg.pid = BTC_PID_SDP;
+    msg.act = BTC_SDP_ACT_DEINIT;
+
+    /* Switch to BTC context */
+    stat = btc_transfer_context(&msg, NULL, 0, NULL);
+    return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
+}
+
+esp_err_t esp_sdp_search_record(esp_bd_addr_t bd_addr, esp_bt_uuid_t uuid)
+{
+    ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+
+    btc_msg_t msg;
+    bt_status_t stat;
+    btc_sdp_args_t arg;
+
+    msg.sig = BTC_SIG_API_CALL;
+    msg.pid = BTC_PID_SDP;
+    msg.act = BTC_SDP_ACT_SEARCH;
+
+    memset(&arg, 0, sizeof(btc_sdp_args_t));
+    memcpy(arg.search.bd_addr, bd_addr, ESP_BD_ADDR_LEN);
+    arg.search.sdp_uuid.len = uuid.len;
+    memcpy(&arg.search.sdp_uuid.uu, &uuid.uuid, sizeof(uuid.uuid));
+
+    /* Switch to BTC context */
+    stat = btc_transfer_context(&msg, &arg, sizeof(btc_sdp_args_t), NULL);
+    return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
+}
+
+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");
+        return ESP_ERR_INVALID_ARG;
+    }
+
+    btc_msg_t msg;
+    bt_status_t stat;
+    btc_sdp_args_t arg;
+
+    msg.sig = BTC_SIG_API_CALL;
+    msg.pid = BTC_PID_SDP;
+    msg.act = BTC_SDP_ACT_CREATE_RECORD;
+
+    memset(&arg, 0, sizeof(btc_sdp_args_t));
+    arg.creat_record.record = (bluetooth_sdp_record *)record;
+
+    /* Switch to BTC context */
+    stat = btc_transfer_context(&msg, &arg, sizeof(btc_sdp_args_t), btc_sdp_arg_deep_copy);
+    return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
+}
+
+esp_err_t esp_sdp_remove_record(int record_handle)
+{
+    ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+
+    btc_msg_t msg;
+    bt_status_t stat;
+    btc_sdp_args_t arg;
+
+    msg.sig = BTC_SIG_API_CALL;
+    msg.pid = BTC_PID_SDP;
+    msg.act = BTC_SDP_ACT_REMOVE_RECORD;
+
+    arg.remove_record.record_handle = record_handle;
+
+    /* Switch to BTC context */
+    stat = btc_transfer_context(&msg, &arg, sizeof(btc_sdp_args_t), NULL);
+    return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
+}
+
+#endif ///defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE

+ 271 - 0
components/bt/host/bluedroid/api/include/api/esp_sdp_api.h

@@ -0,0 +1,271 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __ESP_SDP_API_H__
+#define __ESP_SDP_API_H__
+
+#include "esp_err.h"
+#include "esp_bt_defs.h"
+
+#ifdef __cplusplus
+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 */
+
+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_status_t;
+
+/**
+ * @brief SDP callback function events
+ */
+typedef enum {
+    ESP_SDP_INIT_EVT                    = 0,                /*!< When SDP is inited, the event comes */
+    ESP_SDP_DEINIT_EVT                  = 1,                /*!< When SDP is deinited, 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_bluetooth_sdp_types_t;
+
+/**
+ * @brief Some signals need additional pointers, hence we introduce a
+ *        generic way to handle these pointers.
+ */
+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_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_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_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_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_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_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_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_record_t;
+
+/**
+ * @brief SDP callback parameters union
+ */
+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 */
+
+    /**
+     * @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 */
+
+    /**
+     * @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 */
+
+    /**
+     * @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 */
+
+    /**
+     * @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 */
+
+
+/**
+ * @brief       SDP callback function type.
+ *
+ * @param       event:      Event type
+ * @param       param:      Point to callback parameter, currently is union type
+ */
+typedef void (* esp_sdp_cb_t)(esp_sdp_cb_event_t event, esp_sdp_cb_param_t *param);
+
+/**
+ * @brief       This function is called to init callbacks with SDP module.
+ *
+ * @param[in]   callback:   pointer to the init callback function.
+ *
+ * @return
+ *              - ESP_OK: success
+ *              - other: failed
+ */
+esp_err_t esp_sdp_register_callback(esp_sdp_cb_t callback);
+
+/**
+ * @brief       This function is called to init SDP module.
+ *              When the operation is completed, the callback function will be called with ESP_SDP_INIT_EVT.
+ *              This function should be called after esp_bluedroid_enable() completes successfully.
+ *
+ * @return
+ *              - ESP_OK: success
+ *              - other: failed
+ */
+esp_err_t esp_sdp_init(void);
+
+/**
+ * @brief       This function is called to de-initialize SDP module.
+ *              The operation will remove all SDP records, then the callback function will be called
+ *              with ESP_SDP_REMOVE_RECORD_COMP_EVT, and the number of ESP_SDP_REMOVE_RECORD_COMP_EVT is
+ *              equal to the number of SDP records.When the operation is completed, the callback function
+ *              will be called with ESP_SDP_DEINIT_EVT. This function should be called after esp_sdp_init()
+ *              completes successfully.
+ *
+ * @return
+ *              - ESP_OK: success
+ *              - other: failed
+ */
+esp_err_t esp_sdp_deinit(void);
+
+/**
+ * @brief       This function is called to performs service discovery for the services provided by the given peer device.
+ *              When the operation is completed, the callback function will be called with ESP_SDP_SEARCH_COMP_EVT.
+ *              This funciton must be called after esp_sdp_init() successful and before esp_sdp_deinit().
+ *
+ * @param[in]   bd_addr:   Remote device bluetooth device address.
+ * @param[in]   uuid:      Service UUID of the remote device.
+ *
+ * @return
+ *              - ESP_OK: success
+ *              - other: failed
+ */
+esp_err_t esp_sdp_search_record(esp_bd_addr_t bd_addr, esp_bt_uuid_t uuid);
+
+/**
+ * @brief       This function is called to create SDP records.
+ *              When the operation is completed, the callback function will be called with ESP_SDP_CREATE_RECORD_COMP_EVT.
+ *              This funciton must be called after esp_sdp_init() successful and before esp_sdp_deinit().
+ *
+ * @param[in]   record:   The SDP record to create.
+ *
+ * @return
+ *              - ESP_OK: success
+ *              - other: failed
+ */
+esp_err_t esp_sdp_create_record(esp_bluetooth_sdp_record_t *record);
+
+/**
+ * @brief       This function is called to remove a SDP record.
+ *              When the operation is completed, the callback function will be called with ESP_SDP_REMOVE_RECORD_COMP_EVT.
+ *              This funciton must be called after esp_sdp_init() successful and before esp_sdp_deinit().
+ *
+ * @param[in]   record_handle:    The SDP record handle.
+ *
+ * @return
+ *              - ESP_OK: success
+ *              - other: failed
+ */
+esp_err_t esp_sdp_remove_record(int record_handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif ///__ESP_SDP_API_H__

+ 8 - 6
components/bt/host/bluedroid/bta/include/bta/bta_sdp_api.h

@@ -40,12 +40,13 @@ 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 i/f enabled*/
-#define BTA_SDP_SEARCH_EVT               1  /* SDP Service started */
-#define BTA_SDP_SEARCH_COMP_EVT          2  /* SDP search complete */
-#define BTA_SDP_CREATE_RECORD_USER_EVT   3  /* SDP search complete */
-#define BTA_SDP_REMOVE_RECORD_USER_EVT   4  /* SDP search complete */
-#define BTA_SDP_MAX_EVT                  5  /* max number of SDP events */
+#define BTA_SDP_ENABLE_EVT               0  /* SDP service enabled*/
+#define BTA_SDP_DISENABLE_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 */
+#define BTA_SDP_REMOVE_RECORD_USER_EVT   5  /* SDP remove reocrd complete */
+#define BTA_SDP_MAX_EVT                  6  /* max number of SDP events */
 
 #define BTA_SDP_MAX_RECORDS 15
 
@@ -63,6 +64,7 @@ typedef struct {
 typedef union {
     tBTA_SDP_STATUS              status;            /* BTA_SDP_SEARCH_EVT */
     tBTA_SDP_SEARCH_COMP         sdp_search_comp;   /* BTA_SDP_SEARCH_COMP_EVT */
+    int                          handle;
 } tBTA_SDP;
 
 /* SDP DM Interface callback */

+ 10 - 4
components/bt/host/bluedroid/bta/sdp/bta_sdp_act.c

@@ -439,9 +439,10 @@ static void bta_sdp_search_cback(UINT16 result, void *user_data)
 void bta_sdp_enable(tBTA_SDP_MSG *p_data)
 {
     APPL_TRACE_DEBUG("%s in, sdp_active:%d\n", __func__, bta_sdp_cb.sdp_active);
-    tBTA_SDP_STATUS status = BTA_SDP_SUCCESS;
+    tBTA_SDP bta_sdp;
+    bta_sdp.status = BTA_SDP_SUCCESS;
     bta_sdp_cb.p_dm_cback = p_data->enable.p_cback;
-    bta_sdp_cb.p_dm_cback(BTA_SDP_ENABLE_EVT, (tBTA_SDP *)&status, NULL);
+    bta_sdp_cb.p_dm_cback(BTA_SDP_ENABLE_EVT, (tBTA_SDP *)&bta_sdp, NULL);
 }
 
 /*******************************************************************************
@@ -523,8 +524,11 @@ void bta_sdp_search(tBTA_SDP_MSG *p_data)
 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 bta_sdp;
+    bta_sdp.status = BTA_SDP_SUCCESS;
+    bta_sdp.handle = (int)p_data->record.user_data;
     if (bta_sdp_cb.p_dm_cback) {
-        bta_sdp_cb.p_dm_cback(BTA_SDP_CREATE_RECORD_USER_EVT, NULL, p_data->record.user_data);
+        bta_sdp_cb.p_dm_cback(BTA_SDP_CREATE_RECORD_USER_EVT, &bta_sdp, p_data->record.user_data);
     }
 }
 
@@ -540,8 +544,10 @@ 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 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, NULL, p_data->record.user_data);
+        bta_sdp_cb.p_dm_cback(BTA_SDP_REMOVE_RECORD_USER_EVT, &bta_sdp, p_data->record.user_data);
     }
 }
 

+ 2 - 0
components/bt/host/bluedroid/bta/sdp/bta_sdp_api.c

@@ -102,6 +102,8 @@ tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK *p_cback)
 tBTA_SDP_STATUS BTA_SdpDisable(void)
 {
     tBTA_SDP_STATUS status = BTA_SDP_SUCCESS;
+
+    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);

+ 3 - 2
components/bt/host/bluedroid/btc/profile/std/include/bt_sdp.h

@@ -20,6 +20,7 @@
 #include <stdint.h>
 // #include "bluetooth.h"
 #include "common/bt_defs.h"
+#include "esp_bt_defs.h"
 
 #define SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH 15
 
@@ -38,7 +39,7 @@ typedef enum {
 
 typedef struct _bluetooth_sdp_hdr {
     bluetooth_sdp_types type;
-    bt_uuid_t   uuid;
+    esp_bt_uuid_t       uuid;
     uint32_t    service_name_length;
     char       *service_name;
     int32_t     rfcomm_channel_number;
@@ -52,7 +53,7 @@ typedef struct _bluetooth_sdp_hdr {
  */
 typedef struct _bluetooth_sdp_hdr_overlay {
     bluetooth_sdp_types type;
-    bt_uuid_t   uuid;
+    esp_bt_uuid_t       bt_uuid;
     uint32_t    service_name_length;
     char       *service_name;
     int32_t     rfcomm_channel_number;

+ 53 - 0
components/bt/host/bluedroid/btc/profile/std/include/btc_sdp.h

@@ -0,0 +1,53 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __BTC_SDP_H__
+#define __BTC_SDP_H__
+
+#include "btc/btc_task.h"
+#include "esp_bt_defs.h"
+#include "common/bt_target.h"
+#include "bta/bta_sdp_api.h"
+#include "bt_sdp.h"
+
+#if (defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE)
+
+typedef enum {
+    BTC_SDP_ACT_INIT = 0,
+    BTC_SDP_ACT_DEINIT,
+    BTC_SDP_ACT_SEARCH,
+    BTC_SDP_ACT_CREATE_RECORD,
+    BTC_SDP_ACT_REMOVE_RECORD,
+} btc_sdp_act_t;
+
+/* btc_sdp_args_t */
+typedef union {
+    //BTC_SDP_ACT_SEARCH
+    struct search_record_arg {
+        BD_ADDR bd_addr;
+        tSDP_UUID sdp_uuid;
+    } search;
+
+    //BTC_SDP_ACT_CREATE_RECORD
+    struct creat_record_arg {
+        bluetooth_sdp_record *record;
+    } creat_record;
+
+    //BTC_SDP_ACT_REMOVE_RECORD
+    struct remove_record_arg {
+        int record_handle;
+    } remove_record;
+
+} btc_sdp_args_t;
+
+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);
+
+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 ///__BTC_SDP_H__

+ 1023 - 0
components/bt/host/bluedroid/btc/profile/std/sdp/btc_sdp.c

@@ -0,0 +1,1023 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <string.h>
+
+#include "btc_sdp.h"
+#include "btc/btc_manage.h"
+#include "btc/btc_task.h"
+#include "bta/bta_sdp_api.h"
+#include "bta/bta_sys.h"
+#include "bta/utl.h"
+#include "bt_sdp.h"
+#include "osi/mutex.h"
+#include "osi/allocator.h"
+#include "esp_sdp_api.h"
+
+#if (defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE)
+
+typedef enum {
+    SDP_RECORD_FREE = 0,
+    SDP_RECORD_ALLOCED,
+} sdp_state_t;
+
+typedef struct {
+    sdp_state_t state;
+    int sdp_handle;
+    bluetooth_sdp_record* record_data;
+} sdp_slot_t;
+
+typedef struct {
+    sdp_slot_t *sdp_slots[SDP_MAX_RECORDS];
+    osi_mutex_t sdp_slot_mutex;
+} sdp_local_param_t;
+
+#if SDP_DYNAMIC_MEMORY == FALSE
+static sdp_local_param_t sdp_local_param;
+#else
+static sdp_local_param_t *sdp_local_param_ptr;
+#define sdp_local_param (*sdp_local_param_ptr)
+#endif
+
+#if SDP_DYNAMIC_MEMORY == FALSE
+#define is_sdp_init() (sdp_local_param.sdp_slot_mutex != NULL)
+#else
+#define is_sdp_init() (&sdp_local_param != NULL && sdp_local_param.sdp_slot_mutex != NULL)
+#endif
+
+
+static inline void btc_sdp_cb_to_app(esp_sdp_cb_event_t event, esp_sdp_cb_param_t *param)
+{
+    esp_sdp_cb_t btc_sdp_cb = (esp_sdp_cb_t)btc_profile_cb_get(BTC_PID_SDP);
+    if (btc_sdp_cb) {
+        btc_sdp_cb(event, 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);
+
+    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;
+    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;
+    }
+
+    return records_size;
+}
+
+static void set_sdp_handle(int id, int handle)
+{
+    sdp_slot_t *slot = NULL;
+
+    BTC_TRACE_DEBUG("%s() id=%d to handle=0x%08x", __func__, id, handle);
+
+    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);
+    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;
+    osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
+}
+
+static sdp_slot_t *start_create_sdp(int id)
+{
+    sdp_slot_t *sdp_slot = NULL;
+
+    if(id >= SDP_MAX_RECORDS) {
+        BTC_TRACE_ERROR("%s() failed - id %d is invalid", __func__, id);
+        return NULL;
+    }
+
+    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;
+    }
+    osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
+
+    return sdp_slot;
+}
+
+/* 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)
+{
+    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;
+        }
+    }
+}
+
+static int alloc_sdp_slot(bluetooth_sdp_record* in_record)
+{
+    int i;
+    int record_size = get_sdp_records_size(in_record, 1);
+    bluetooth_sdp_record *record = NULL;
+    sdp_slot_t **slot = NULL;
+
+    record = osi_malloc(record_size);
+    if (record == NULL) {
+        BTC_TRACE_ERROR("%s() osi_malloc failed!", __func__);
+        return -1;
+    }
+
+    copy_sdp_records(in_record, record, 1);
+
+    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;
+            }
+            (*slot)->state = SDP_RECORD_ALLOCED;
+            (*slot)->record_data = record;
+            break;
+        }
+    }
+    osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
+    if(i >= SDP_MAX_RECORDS) {
+        BTC_TRACE_ERROR("%s() failed - no more free slots!", __func__);
+        osi_free(record);
+        return -1;
+    }
+
+    return i;
+}
+
+static int free_sdp_slot(int id)
+{
+    int handle = -1;
+    bluetooth_sdp_record *record = NULL;
+    sdp_slot_t *slot = NULL;
+
+    if(id >= SDP_MAX_RECORDS) {
+        APPL_TRACE_ERROR("%s() failed - id %d is invalid", __func__, id);
+        return handle;
+    }
+    slot = sdp_local_param.sdp_slots[id];
+    if (slot == NULL) {
+        // already freed
+        return handle;
+    }
+
+    osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
+    handle = slot->sdp_handle;
+    if (slot->state != SDP_RECORD_FREE) {
+        /* safe a copy of the pointer, and free after unlock() */
+        record = slot->record_data;
+    }
+    osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
+
+    if(record != NULL) {
+        osi_free(record);
+    } else {
+        // Record have already been freed
+        handle = -1;
+    }
+    osi_free(slot);
+    slot = NULL;
+
+    return handle;
+}
+
+/* Create a MAP MAS SDP record based on information stored in a bluetooth_sdp_mas_record */
+static int add_maps_sdp(const bluetooth_sdp_mas_record* rec)
+{
+    tSDP_PROTOCOL_ELEM  protoList [3];
+    UINT16              service = UUID_SERVCLASS_MESSAGE_ACCESS;
+    UINT16              browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
+    bool                status = true;
+    UINT32              sdp_handle = 0;
+    UINT8               temp[4];
+    UINT8*              p_temp = temp;
+
+    BTC_TRACE_DEBUG("%s(): MASID = 0x%02x, scn 0x%02x, psm = 0x%04x\n  service name %s", __func__,
+            rec->mas_instance_id, rec->hdr.rfcomm_channel_number,
+            rec->hdr.l2cap_psm, rec->hdr.service_name);
+
+    BTC_TRACE_DEBUG("  msg_types: 0x%02x, feature_bits: 0x%08x",
+            rec->supported_message_types, rec->supported_features);
+
+    if ((sdp_handle = SDP_CreateRecord()) == 0) {
+        BTC_TRACE_ERROR("%s() - Unable to register MAPS Service", __func__);
+        return sdp_handle;
+    }
+
+    /* add service class */
+    status &= SDP_AddServiceClassIdList(sdp_handle, 1, &service);
+    memset( protoList, 0 , 3*sizeof(tSDP_PROTOCOL_ELEM) );
+
+    /* add protocol list, including RFCOMM scn */
+    protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
+    protoList[0].num_params = 0;
+    protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
+    protoList[1].num_params = 1;
+    protoList[1].params[0] = rec->hdr.rfcomm_channel_number;
+    protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
+    protoList[2].num_params = 0;
+    status &= SDP_AddProtocolList(sdp_handle, 3, protoList);
+
+    /* Add a name entry */
+    status &= SDP_AddAttribute(sdp_handle,
+                    (UINT16)ATTR_ID_SERVICE_NAME,
+                    (UINT8)TEXT_STR_DESC_TYPE,
+                    (UINT32)(rec->hdr.service_name_length + 1),
+                    (UINT8 *)rec->hdr.service_name);
+
+    /* Add in the Bluetooth Profile Descriptor List */
+    status &= SDP_AddProfileDescriptorList(sdp_handle,
+                                     UUID_SERVCLASS_MAP_PROFILE,
+                                     rec->hdr.profile_version);
+
+    /* Add MAS instance ID */
+    status &= SDP_AddAttribute(sdp_handle, ATTR_ID_MAS_INSTANCE_ID, UINT_DESC_TYPE,
+              (UINT32)1, (UINT8*)&rec->mas_instance_id);
+
+    /* Add supported message types */
+    status &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_MSG_TYPE, UINT_DESC_TYPE,
+              (UINT32)1, (UINT8*)&rec->supported_message_types);
+
+    /* Add supported feature */
+    UINT32_TO_BE_STREAM(p_temp, rec->supported_features);
+    status &= SDP_AddAttribute(sdp_handle, ATTR_ID_MAP_SUPPORTED_FEATURES,
+            UINT_DESC_TYPE, (UINT32)4, temp);
+
+    /* Add the L2CAP PSM if present */
+    if(rec->hdr.l2cap_psm != -1) {
+        p_temp = temp;// The macro modifies p_temp, hence rewind.
+        UINT16_TO_BE_STREAM(p_temp, rec->hdr.l2cap_psm);
+        status &= SDP_AddAttribute(sdp_handle, ATTR_ID_GOEP_L2CAP_PSM,
+                UINT_DESC_TYPE, (UINT32)2, temp);
+    }
+
+    /* Make the service browseable */
+    status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
+
+    if (!status) {
+        SDP_DeleteRecord(sdp_handle);
+        sdp_handle = 0;
+        BTC_TRACE_ERROR("%s() FAILED", __func__);
+    } else {
+        bta_sys_add_uuid(service);  /* UUID_SERVCLASS_MESSAGE_ACCESS */
+        BTC_TRACE_DEBUG("%s():  SDP Registered (handle 0x%08x)", __func__, sdp_handle);
+    }
+
+    return sdp_handle;
+}
+
+/* Create a MAP MNS SDP record based on information stored in a bluetooth_sdp_mns_record */
+static int add_mapc_sdp(const bluetooth_sdp_mns_record* rec)
+{
+    tSDP_PROTOCOL_ELEM  protoList [3];
+    UINT16              service = UUID_SERVCLASS_MESSAGE_NOTIFICATION;
+    UINT16              browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
+    bool                status = true;
+    UINT32              sdp_handle = 0;
+    UINT8               temp[4];
+    UINT8*              p_temp = temp;
+
+    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);
+
+    BTC_TRACE_DEBUG("  feature_bits: 0x%08x", rec->supported_features);
+
+    if ((sdp_handle = SDP_CreateRecord()) == 0) {
+        BTC_TRACE_ERROR("%s(): Unable to register MAP Notification Service", __func__);
+        return sdp_handle;
+    }
+
+    /* add service class */
+    status &= SDP_AddServiceClassIdList(sdp_handle, 1, &service);
+    memset( protoList, 0 , 3*sizeof(tSDP_PROTOCOL_ELEM) );
+
+    /* add protocol list, including RFCOMM scn */
+    protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
+    protoList[0].num_params = 0;
+    protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
+    protoList[1].num_params = 1;
+    protoList[1].params[0] = rec->hdr.rfcomm_channel_number;
+    protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
+    protoList[2].num_params = 0;
+    status &= SDP_AddProtocolList(sdp_handle, 3, protoList);
+
+    /* Add a name entry */
+    status &= SDP_AddAttribute(sdp_handle,
+                    (UINT16)ATTR_ID_SERVICE_NAME,
+                    (UINT8)TEXT_STR_DESC_TYPE,
+                    (UINT32)(rec->hdr.service_name_length + 1),
+                    (UINT8 *)rec->hdr.service_name);
+
+    /* Add in the Bluetooth Profile Descriptor List */
+    status &= SDP_AddProfileDescriptorList(sdp_handle,
+                                     UUID_SERVCLASS_MAP_PROFILE,
+                                     rec->hdr.profile_version);
+
+    /* Add supported feature */
+    UINT32_TO_BE_STREAM(p_temp, rec->supported_features);
+    status &= SDP_AddAttribute(sdp_handle, ATTR_ID_MAP_SUPPORTED_FEATURES,
+            UINT_DESC_TYPE, (UINT32)4, temp);
+
+    /* Add the L2CAP PSM if present */
+    if(rec->hdr.l2cap_psm != -1) {
+        p_temp = temp;// The macro modifies p_temp, hence rewind.
+        UINT16_TO_BE_STREAM(p_temp, rec->hdr.l2cap_psm);
+        status &= SDP_AddAttribute(sdp_handle, ATTR_ID_GOEP_L2CAP_PSM,
+                UINT_DESC_TYPE, (UINT32)2, temp);
+    }
+
+    /* Make the service browseable */
+    status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
+
+    if (!status) {
+        SDP_DeleteRecord(sdp_handle);
+        sdp_handle = 0;
+        BTC_TRACE_ERROR("%s() FAILED", __func__);
+    } else {
+        bta_sys_add_uuid(service);  /* UUID_SERVCLASS_MESSAGE_ACCESS */
+        BTC_TRACE_DEBUG("%s():  SDP Registered (handle 0x%08x)", __func__, sdp_handle);
+    }
+
+    return sdp_handle;
+}
+
+/* Create a PBAP Server SDP record based on information stored in a bluetooth_sdp_pse_record */
+static int add_pbaps_sdp(const bluetooth_sdp_pse_record* rec)
+{
+    tSDP_PROTOCOL_ELEM  protoList [3];
+    UINT16              service = UUID_SERVCLASS_PBAP_PSE;
+    UINT16              browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
+    bool                status = true;
+    UINT32              sdp_handle = 0;
+    UINT8               temp[4];
+    UINT8*              p_temp = temp;
+
+    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);
+
+    BTC_TRACE_DEBUG("  supported_repositories: 0x%08x, feature_bits: 0x%08x",
+            rec->supported_repositories, rec->supported_features);
+
+    if ((sdp_handle = SDP_CreateRecord()) == 0) {
+        BTC_TRACE_ERROR("%s(): Unable to register PBAP Server Service", __func__);
+        return sdp_handle;
+    }
+
+    /* add service class */
+    status &= SDP_AddServiceClassIdList(sdp_handle, 1, &service);
+    memset( protoList, 0 , 3*sizeof(tSDP_PROTOCOL_ELEM) );
+
+    /* add protocol list, including RFCOMM scn */
+    protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
+    protoList[0].num_params = 0;
+    protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
+    protoList[1].num_params = 1;
+    protoList[1].params[0] = rec->hdr.rfcomm_channel_number;
+    protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
+    protoList[2].num_params = 0;
+    status &= SDP_AddProtocolList(sdp_handle, 3, protoList);
+
+    /* Add a name entry */
+    status &= SDP_AddAttribute(sdp_handle,
+                    (UINT16)ATTR_ID_SERVICE_NAME,
+                    (UINT8)TEXT_STR_DESC_TYPE,
+                    (UINT32)(rec->hdr.service_name_length + 1),
+                    (UINT8 *)rec->hdr.service_name);
+
+    /* Add in the Bluetooth Profile Descriptor List */
+    status &= SDP_AddProfileDescriptorList(sdp_handle,
+                                     UUID_SERVCLASS_PHONE_ACCESS,
+                                     rec->hdr.profile_version);
+
+    /* Add supported repositories 1 byte */
+    status &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_REPOSITORIES,
+            UINT_DESC_TYPE, (UINT32)1, (UINT8*)&rec->supported_repositories);
+
+    /* Add supported feature 4 bytes*/
+    UINT32_TO_BE_STREAM(p_temp, rec->supported_features);
+    status &= SDP_AddAttribute(sdp_handle, ATTR_ID_PBAP_SUPPORTED_FEATURES,
+            UINT_DESC_TYPE, (UINT32)4, temp);
+
+    /* Add the L2CAP PSM if present */
+    if(rec->hdr.l2cap_psm != -1) {
+        p_temp = temp;// The macro modifies p_temp, hence rewind.
+        UINT16_TO_BE_STREAM(p_temp, rec->hdr.l2cap_psm);
+        status &= SDP_AddAttribute(sdp_handle, ATTR_ID_GOEP_L2CAP_PSM,
+                UINT_DESC_TYPE, (UINT32)2, temp);
+    }
+
+    /* Make the service browseable */
+    status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
+
+    if (!status) {
+        SDP_DeleteRecord(sdp_handle);
+        sdp_handle = 0;
+        BTC_TRACE_ERROR("%s() FAILED", __func__);
+    } else {
+        bta_sys_add_uuid(service);  /* UUID_SERVCLASS_MESSAGE_ACCESS */
+        BTC_TRACE_DEBUG("%s():  SDP Registered (handle 0x%08x)", __func__, sdp_handle);
+    }
+
+    return sdp_handle;
+}
+
+
+/* Create a OPP Server SDP record based on information stored in a bluetooth_sdp_ops_record */
+static int add_opps_sdp(const bluetooth_sdp_ops_record* rec)
+{
+    tSDP_PROTOCOL_ELEM  protoList [3];
+    UINT16              service = UUID_SERVCLASS_OBEX_OBJECT_PUSH;
+    UINT16              browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
+    UINT8               type_len[rec->supported_formats_list_len];
+    UINT8               desc_type[rec->supported_formats_list_len];
+    UINT8              *type_value[rec->supported_formats_list_len];
+    bool                status = true;
+    UINT32              sdp_handle = 0;
+    UINT8               temp[4];
+    UINT8*              p_temp = temp;
+    tBTA_UTL_COD        cod;
+    int i,j;
+
+    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);
+
+    BTC_TRACE_DEBUG("  supported formats count: %d",
+            rec->supported_formats_list_len);
+
+    if ((sdp_handle = SDP_CreateRecord()) == 0) {
+        BTC_TRACE_ERROR("%s(): Unable to register Object Push Server Service", __func__);
+        return sdp_handle;
+    }
+
+    /* add service class */
+    status &= SDP_AddServiceClassIdList(sdp_handle, 1, &service);
+    memset( protoList, 0 , 3*sizeof(tSDP_PROTOCOL_ELEM) );
+
+    /* add protocol list, including RFCOMM scn */
+    protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
+    protoList[0].num_params = 0;
+    protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
+    protoList[1].num_params = 1;
+    protoList[1].params[0] = rec->hdr.rfcomm_channel_number;
+    protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
+    protoList[2].num_params = 0;
+    status &= SDP_AddProtocolList(sdp_handle, 3, protoList);
+
+    /* Add a name entry */
+    status &= SDP_AddAttribute(sdp_handle,
+                    (UINT16)ATTR_ID_SERVICE_NAME,
+                    (UINT8)TEXT_STR_DESC_TYPE,
+                    (UINT32)(rec->hdr.service_name_length + 1),
+                    (UINT8 *)rec->hdr.service_name);
+
+    /* Add in the Bluetooth Profile Descriptor List */
+    status &= SDP_AddProfileDescriptorList(sdp_handle,
+                                     UUID_SERVCLASS_OBEX_OBJECT_PUSH,
+                                     rec->hdr.profile_version);
+
+    /* add sequence for supported types */
+    for (i = 0, j = 0; i < rec->supported_formats_list_len; i++) {
+        type_value[j] = (UINT8 *) &rec->supported_formats_list[i];
+        desc_type[j] = UINT_DESC_TYPE;
+        type_len[j++] = 1;
+    }
+
+    status &= SDP_AddSequence(sdp_handle, (UINT16) ATTR_ID_SUPPORTED_FORMATS_LIST,
+        (UINT8) rec->supported_formats_list_len, desc_type, type_len, type_value);
+
+    /* Add the L2CAP PSM if present */
+    if(rec->hdr.l2cap_psm != -1) {
+        p_temp = temp;// The macro modifies p_temp, hence rewind.
+        UINT16_TO_BE_STREAM(p_temp, rec->hdr.l2cap_psm);
+        status &= SDP_AddAttribute(sdp_handle, ATTR_ID_GOEP_L2CAP_PSM,
+                UINT_DESC_TYPE, (UINT32)2, temp);
+    }
+
+    /* Make the service browseable */
+    status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
+
+    if (!status) {
+        SDP_DeleteRecord(sdp_handle);
+        sdp_handle = 0;
+        BTC_TRACE_ERROR("%s() FAILED", __func__);
+    } else {
+        /* set class of device */
+        cod.service = BTM_COD_SERVICE_OBJ_TRANSFER;
+        utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
+
+        bta_sys_add_uuid(service);  /* UUID_SERVCLASS_OBEX_OBJECT_PUSH */
+        BTC_TRACE_DEBUG("%s():  SDP Registered (handle 0x%08x)", __func__, sdp_handle);
+    }
+
+    return sdp_handle;
+}
+
+// Create a Sim Access Profile SDP record based on information stored in a bluetooth_sdp_sap_record.
+static int add_saps_sdp(const bluetooth_sdp_sap_record* rec)
+{
+    tSDP_PROTOCOL_ELEM  protoList [2];
+    UINT16              services[2];
+    UINT16              browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
+    bool                status = true;
+    UINT32              sdp_handle = 0;
+
+    BTC_TRACE_DEBUG("%s(): scn 0x%02x, service name %s", __func__,
+            rec->hdr.rfcomm_channel_number, rec->hdr.service_name);
+
+    if ((sdp_handle = SDP_CreateRecord()) == 0) {
+        BTC_TRACE_ERROR("%s(): Unable to register SAPS Service", __func__);
+        return sdp_handle;
+    }
+
+    services[0] = UUID_SERVCLASS_SAP;
+    services[1] = UUID_SERVCLASS_GENERIC_TELEPHONY;
+
+    // add service class
+    status &= SDP_AddServiceClassIdList(sdp_handle, 2, services);
+    memset(protoList, 0, 2 * sizeof(tSDP_PROTOCOL_ELEM));
+
+    // add protocol list, including RFCOMM scn
+    protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
+    protoList[0].num_params = 0;
+    protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
+    protoList[1].num_params = 1;
+    protoList[1].params[0] = rec->hdr.rfcomm_channel_number;
+    status &= SDP_AddProtocolList(sdp_handle, 2, protoList);
+
+    // Add a name entry
+    status &= SDP_AddAttribute(sdp_handle,
+                    (UINT16)ATTR_ID_SERVICE_NAME,
+                    (UINT8)TEXT_STR_DESC_TYPE,
+                    (UINT32)(rec->hdr.service_name_length + 1),
+                    (UINT8 *)rec->hdr.service_name);
+
+    // Add in the Bluetooth Profile Descriptor List
+    status &= SDP_AddProfileDescriptorList(sdp_handle,
+            UUID_SERVCLASS_SAP,
+            rec->hdr.profile_version);
+
+    // Make the service browseable
+    status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
+
+    if (!status) {
+        SDP_DeleteRecord(sdp_handle);
+        sdp_handle = 0;
+        BTC_TRACE_ERROR("%s(): FAILED deleting record", __func__);
+    } else {
+        bta_sys_add_uuid(UUID_SERVCLASS_SAP);
+        BTC_TRACE_DEBUG("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle);
+    }
+
+    return sdp_handle;
+}
+
+static int btc_handle_create_record_event(int id)
+{
+    int handle = -1;
+    const sdp_slot_t *sdp_slot = NULL;
+
+    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) {
+        case SDP_TYPE_MAP_MAS:
+            handle = add_maps_sdp(&record->mas);
+            break;
+        case SDP_TYPE_MAP_MNS:
+            handle = add_mapc_sdp(&record->mns);
+            break;
+        case SDP_TYPE_PBAP_PSE:
+            handle = add_pbaps_sdp(&record->pse);
+            break;
+        case SDP_TYPE_OPP_SERVER:
+            handle = add_opps_sdp(&record->ops);
+            break;
+        case SDP_TYPE_SAP_SERVER:
+            handle = add_saps_sdp(&record->sap);
+            break;
+        case SDP_TYPE_PBAP_PCE:
+            // break; not yet supported
+        default:
+            BTC_TRACE_DEBUG("Record type %d is not supported",record->hdr.type);
+            break;
+        }
+        if(handle != -1) {
+            set_sdp_handle(id, handle);
+        }
+    }
+
+    return handle;
+}
+
+static bool btc_sdp_remove_record_event(int 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);
+        }
+    }
+
+    return result;
+}
+
+static void btc_sdp_dm_cback(tBTA_SDP_EVT event, tBTA_SDP* p_data, void* user_data)
+{
+    btc_msg_t msg;
+    bt_status_t status;
+
+    switch (event) {
+    case BTA_SDP_CREATE_RECORD_USER_EVT: {
+        if (p_data->status == BTA_SDP_SUCCESS) {
+            if(btc_handle_create_record_event((int)user_data) < 0) {
+                p_data->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;
+            }
+        }
+    }
+    break;
+    default:
+        break;
+    }
+
+    msg.sig = BTC_SIG_API_CB;
+    msg.pid = BTC_PID_SDP;
+    msg.act = event;
+
+    status = btc_transfer_context(&msg, p_data, sizeof(tBTA_SDP), NULL);
+
+    if (status != BT_STATUS_SUCCESS) {
+        BTC_TRACE_ERROR("%s btc_transfer_context failed", __func__);
+    }
+}
+
+static void btc_sdp_init(void)
+{
+    esp_sdp_cb_param_t param;
+    esp_sdp_status_t ret = ESP_SDP_SUCCESS;
+
+    do {
+        if (is_sdp_init()) {
+            BTC_TRACE_ERROR("%s SDP has been initiated, shall deinit first!", __func__);
+            ret = ESP_SDP_NEED_DEINIT;
+            break;
+        }
+
+#if SDP_DYNAMIC_MEMORY == TRUE
+        if ((sdp_local_param_ptr = (sdp_local_param_t *)osi_malloc(sizeof(sdp_local_param_t))) == NULL) {
+            BTC_TRACE_ERROR("%s malloc failed\n", __func__);
+            ret = ESP_SDP_NO_RESOURCE;
+            break;
+        }
+        memset((void *)sdp_local_param_ptr, 0, sizeof(sdp_local_param_t));
+#endif
+
+        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);
+    } while(0);
+
+    if (ret != ESP_SDP_SUCCESS) {
+        param.init.status = ret;
+        btc_sdp_cb_to_app(ESP_SDP_INIT_EVT, &param);
+    }
+}
+
+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()) {
+            BTC_TRACE_ERROR("%s SDP has not been initiated, shall init first!", __func__);
+            ret = ESP_SDP_NEED_INIT;
+            break;
+        }
+
+        for(int i = 0; i < SDP_MAX_RECORDS; i++) {
+            handle = free_sdp_slot(i);
+            if (handle > 0) {
+                BTA_SdpRemoveRecordByUser((void*)handle);
+            }
+        }
+        // todo
+        sdp_disable_handler();
+    } while(0);
+
+    if (ret != ESP_SDP_SUCCESS) {
+        param.deinit.status = ret;
+        btc_sdp_cb_to_app(ESP_SDP_DEINIT_EVT, &param);
+    }
+}
+
+static void btc_sdp_create_record(btc_sdp_args_t *arg)
+{
+    int handle;
+    esp_sdp_cb_param_t param;
+    esp_sdp_status_t ret = ESP_SDP_SUCCESS;
+
+    do {
+        if (!is_sdp_init()) {
+            BTC_TRACE_ERROR("%s SDP has not been initiated, shall init first!", __func__);
+            ret = ESP_SDP_NEED_INIT;
+            break;
+        }
+
+        handle = alloc_sdp_slot(arg->creat_record.record);
+        if (handle < 0) {
+            ret = ESP_SDP_FAILURE;
+            break;
+        }
+
+        BTA_SdpCreateRecordByUser((void *) handle);
+    } while(0);
+
+    if (ret != ESP_SDP_SUCCESS) {
+        param.create_record.status = ret;
+        param.create_record.record_handle = -1;
+        btc_sdp_cb_to_app(ESP_SDP_CREATE_RECORD_COMP_EVT, &param);
+    }
+}
+
+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;
+
+    do {
+        if (!is_sdp_init()) {
+            BTC_TRACE_ERROR("%s SDP has not been initiated, shall init first!", __func__);
+            ret = ESP_SDP_NEED_INIT;
+            break;
+        }
+
+        /* Get the Record handle, and free the slot */
+        /* The application layer record_handle is equivalent to the id of the btc layer */
+        handle = free_sdp_slot(arg->remove_record.record_handle);
+
+        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;
+        }
+    } while(0);
+
+    if (ret != ESP_SDP_SUCCESS) {
+        param.create_record.status = ret;
+        btc_sdp_cb_to_app(ESP_SDP_REMOVE_RECORD_COMP_EVT, &param);
+    }
+}
+
+static void btc_sdp_search(btc_sdp_args_t *arg)
+{
+    esp_sdp_cb_param_t param = {0};
+    esp_sdp_status_t ret = ESP_SDP_SUCCESS;
+
+    do {
+        if (!is_sdp_init()) {
+            BTC_TRACE_ERROR("%s SDP has not been initiated, shall init first!", __func__);
+            ret = ESP_SDP_NEED_INIT;
+            break;
+        }
+
+        BTA_SdpSearch(arg->search.bd_addr, &arg->search.sdp_uuid);
+    } while(0);
+
+    if (ret != ESP_SDP_SUCCESS) {
+        param.search.status = ret;
+        btc_sdp_cb_to_app(ESP_SDP_SEARCH_COMP_EVT, &param);
+    }
+}
+
+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));
+        } 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);
+        }
+        break;
+    default:
+        break;
+    }
+}
+
+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);
+        }
+        break;
+    default:
+        break;
+    }
+}
+
+void btc_sdp_call_handler(btc_msg_t *msg)
+{
+    btc_sdp_args_t *arg = (btc_sdp_args_t *)(msg->arg);
+
+    BTC_TRACE_DEBUG("%s: event = %d\n", __func__, msg->act);
+
+    switch (msg->act) {
+    case BTC_SDP_ACT_INIT:
+        btc_sdp_init();
+        break;
+    case BTC_SDP_ACT_DEINIT:
+        btc_sdp_deinit();
+        break;
+    case BTC_SDP_ACT_SEARCH:
+        btc_sdp_search(arg);
+        break;
+    case BTC_SDP_ACT_CREATE_RECORD:
+        btc_sdp_create_record(arg);
+        break;
+    case BTC_SDP_ACT_REMOVE_RECORD:
+        btc_sdp_remove_record(arg);
+        break;
+    default:
+        BTC_TRACE_ERROR("%s: Unhandled event (%d)!\n", __func__, msg->act);
+        break;
+    }
+    btc_sdp_arg_deep_free(msg);
+}
+
+void btc_sdp_cb_handler(btc_msg_t *msg)
+{
+    esp_sdp_cb_param_t param = {0};
+    uint8_t event = msg->act;
+    tBTA_SDP *p_data = (tBTA_SDP *)msg->arg;
+
+    switch(event) {
+    case BTA_SDP_ENABLE_EVT:
+        param.init.status = p_data->status;
+        btc_sdp_cb_to_app(ESP_SDP_INIT_EVT, &param);
+        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
+        param.deinit.status = ESP_SDP_SUCCESS;
+        btc_sdp_cb_to_app(ESP_SDP_DEINIT_EVT, &param);
+        break;
+    case BTA_SDP_SEARCH_COMP_EVT:
+        param.search.status = p_data->status;
+        if (param.search.status == ESP_SDP_SUCCESS) {
+            memcpy(param.search.remote_addr, p_data->sdp_search_comp.remote_addr, sizeof(BD_ADDR));
+            memcpy(&param.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;
+            }
+        }
+        btc_sdp_cb_to_app(ESP_SDP_SEARCH_COMP_EVT, &param);
+        if (param.search.records != NULL) {
+            osi_free(param.search.records);
+        }
+        break;
+    case BTA_SDP_CREATE_RECORD_USER_EVT:
+        param.create_record.status = p_data->status;
+        param.create_record.record_handle = p_data->handle;
+        btc_sdp_cb_to_app(ESP_SDP_CREATE_RECORD_COMP_EVT, &param);
+        break;
+    case BTA_SDP_REMOVE_RECORD_USER_EVT:
+        param.remove_record.status = p_data->status;
+        btc_sdp_cb_to_app(ESP_SDP_REMOVE_RECORD_COMP_EVT, &param);
+        break;
+    default:
+        BTC_TRACE_DEBUG("%s: Unhandled event (%d)!", __func__, msg->act);
+        break;
+    }
+}
+
+#endif ///defined BTC_SDP_INCLUDED && BTC_SDP_INCLUDED == TRUE

+ 2 - 1
components/bt/host/bluedroid/common/include/common/bt_target.h

@@ -87,6 +87,7 @@
 #define BTA_JV_INCLUDED             TRUE
 #define RFCOMM_INCLUDED             TRUE
 #define BTC_L2CAP_INCLUDED          TRUE
+#define BTC_SDP_INCLUDED            TRUE
 #define VND_BT_JV_BTA_L2CAP         TRUE
 #endif /* UC_BT_L2CAP_ENABLED */
 
@@ -1412,7 +1413,7 @@
 
 /* The maximum number of attributes in each record. */
 #ifndef SDP_MAX_REC_ATTR
-#if defined(HID_DEV_INCLUDED) && (HID_DEV_INCLUDED==TRUE)
+#if (defined(HID_DEV_INCLUDED) && (HID_DEV_INCLUDED==TRUE)) || (defined(BTC_SDP_INCLUDED) && (BTC_SDP_INCLUDED==TRUE))
 #define SDP_MAX_REC_ATTR            25
 #else
 #define SDP_MAX_REC_ATTR            8