Merge branch 'feature/add_di_api' into 'master'

Feature/add di api

Closes IDFGH-11785

See merge request espressif/esp-idf!32872
This commit is contained in:
Wang Meng Yang
2024-09-06 17:11:19 +08:00
28 changed files with 931 additions and 442 deletions

View File

@ -42,9 +42,9 @@
#if (BTC_L2CAP_INCLUDED == TRUE) #if (BTC_L2CAP_INCLUDED == TRUE)
#include "btc_l2cap.h" #include "btc_l2cap.h"
#endif /* #if (BTC_L2CAP_INCLUDED == TRUE) */ #endif /* #if (BTC_L2CAP_INCLUDED == TRUE) */
#if (BTC_SDP_INCLUDED == TRUE) #if (BTC_SDP_COMMON_INCLUDED == TRUE)
#include "btc_sdp.h" #include "btc_sdp.h"
#endif /* #if (BTC_SDP_INCLUDED == TRUE) */ #endif /* #if (BTC_SDP_COMMON_INCLUDED == TRUE) */
#if BTC_HF_INCLUDED #if BTC_HF_INCLUDED
#include "btc_hf_ag.h" #include "btc_hf_ag.h"
#endif/* #if BTC_HF_INCLUDED */ #endif/* #if BTC_HF_INCLUDED */
@ -138,9 +138,9 @@ static const btc_func_t profile_tab[BTC_PID_NUM] = {
#if (BTC_L2CAP_INCLUDED == TRUE) #if (BTC_L2CAP_INCLUDED == TRUE)
[BTC_PID_L2CAP] = {btc_l2cap_call_handler, btc_l2cap_cb_handler }, [BTC_PID_L2CAP] = {btc_l2cap_call_handler, btc_l2cap_cb_handler },
#endif /* #if (BTC_L2CAP_INCLUDED == TRUE) */ #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 }, [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 #if BTC_HF_INCLUDED
[BTC_PID_HF] = {btc_hf_call_handler, btc_hf_cb_handler}, [BTC_PID_HF] = {btc_hf_call_handler, btc_hf_cb_handler},
#endif /* #if BTC_HF_INCLUDED */ #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. * transfer an message to another module in the different task.
* @param msg message * @param msg message
* @param arg paramter * @param arg parameter
* @param arg_len length of paramter * @param arg_len length of parameter
* @param copy_func deep copy function * @param copy_func deep copy function
* @param free_func deep free function * @param free_func deep free function
* @return BT_STATUS_SUCCESS: success * @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 * @param msg message
* @return BT_STATUS_SUCCESS: success * @return BT_STATUS_SUCCESS: success
* others: fail * others: fail

View File

@ -102,6 +102,13 @@ config BT_L2CAP_ENABLED
This enables the Logical Link Control and Adaptation Layer Protocol. This enables the Logical Link Control and Adaptation Layer Protocol.
Only supported classic bluetooth. 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 menuconfig BT_HFP_ENABLE
bool "Hands Free/Handset Profile" bool "Hands Free/Handset Profile"
depends on BT_CLASSIC_ENABLED depends on BT_CLASSIC_ENABLED
@ -148,7 +155,7 @@ menuconfig BT_HID_ENABLED
depends on BT_CLASSIC_ENABLED depends on BT_CLASSIC_ENABLED
default n default n
help help
This enables the BT HID Host This enables the BT HID functionalities
config BT_HID_HOST_ENABLED config BT_HID_HOST_ENABLED
bool "Classic BT HID Host" bool "Classic BT HID Host"

View File

@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -8,12 +8,43 @@
#include "esp_bt_main.h" #include "esp_bt_main.h"
#include "btc/btc_manage.h" #include "btc/btc_manage.h"
#include "stack/sdpdefs.h"
#include "btc_sdp.h" #include "btc_sdp.h"
#include "esp_sdp_api.h" #include "esp_sdp_api.h"
#include "common/bt_target.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) 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); ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (record == NULL || record->hdr.service_name_length > ESP_SDP_SERVER_NAME_MAX if (!esp_sdp_record_integrity_check(record)) {
|| strlen(record->hdr.service_name)+1 != record->hdr.service_name_length) {
LOG_ERROR("Invalid server name!\n");
return ESP_ERR_INVALID_ARG; 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; msg.act = BTC_SDP_ACT_CREATE_RECORD;
memset(&arg, 0, sizeof(btc_sdp_args_t)); 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 */ /* Switch to BTC context */
stat = btc_transfer_context(&msg, &arg, sizeof(btc_sdp_args_t), 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; 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

View File

@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -14,123 +14,163 @@
extern "C" { extern "C" {
#endif #endif
#define ESP_SDP_SERVER_NAME_MAX 32 /*!< Service name max 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 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 { typedef enum {
ESP_SDP_SUCCESS = 0, /*!< Successful operation. */ ESP_SDP_SUCCESS = 0, /*!< Successful operation. */
ESP_SDP_FAILURE, /*!< Generic failure. */ ESP_SDP_FAILURE, /*!< Generic failure. */
ESP_SDP_NO_RESOURCE, /*!< No more resource */ ESP_SDP_NO_RESOURCE, /*!< No more resource */
ESP_SDP_NEED_INIT, /*!< SDP module shall init first */ ESP_SDP_NEED_INIT, /*!< SDP module shall init first */
ESP_SDP_NEED_DEINIT, /*!< SDP module shall deinit first */ ESP_SDP_NEED_DEINIT, /*!< SDP module shall deinit first */
ESP_SDP_NO_CREATE_RECORD, /*!< No record created */ ESP_SDP_NO_CREATE_RECORD, /*!< No record created */
} esp_sdp_status_t; } esp_sdp_status_t;
/** /**
* @brief SDP callback function events * @brief SDP callback function events
*/ */
typedef enum { typedef enum {
ESP_SDP_INIT_EVT = 0, /*!< When SDP is initialized, the event comes */ 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_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_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_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_REMOVE_RECORD_COMP_EVT = 4, /*!< When remove a SDP record complete, the event comes */
} esp_sdp_cb_event_t; } esp_sdp_cb_event_t;
/** /**
* @brief SDP record type * @brief SDP record type
*/ */
typedef enum { typedef enum {
ESP_SDP_TYPE_RAW, /*!< Used to carry raw SDP search data for unknown UUIDs */ 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_MAS, /*!< Message Access Profile - Server */
ESP_SDP_TYPE_MAP_MNS, /*!< Message Access Profile - Client (Notification 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_PSE, /*!< Phone Book Profile - Server */
ESP_SDP_TYPE_PBAP_PCE, /*!< Phone Book Profile - Client */ ESP_SDP_TYPE_PBAP_PCE, /*!< Phone Book Profile - Client */
ESP_SDP_TYPE_OPP_SERVER, /*!< Object Push Profile */ ESP_SDP_TYPE_OPP_SERVER, /*!< Object Push Profile */
ESP_SDP_TYPE_SAP_SERVER /*!< SIM Access Profile */ ESP_SDP_TYPE_SAP_SERVER, /*!< SIM Access Profile */
ESP_SDP_TYPE_DIP_SERVER, /*!< Device Identification Profile */
} esp_bluetooth_sdp_types_t; } esp_bluetooth_sdp_types_t;
/** /**
* @brief Some signals need additional pointers, hence we introduce a * @brief SDP header structure
* generic way to handle these pointers.
*/ */
typedef struct bluetooth_sdp_hdr_overlay { typedef struct {
esp_bluetooth_sdp_types_t type; /*!< SDP type */ 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 */
uint32_t service_name_length; /*!< Service name length */ char *service_name; /*!< Service name */
char *service_name; /*!< service name */ int32_t rfcomm_channel_number; /*!< RFCOMM channel number, if not used set to -1*/
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 l2cap_psm; /*!< l2cap psm, if not used set to -1 */ int32_t profile_version; /*!< Profile version */
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 */ * @brief Raw SDP record
uint8_t *user1_ptr; /*!< see esp_bluetooth_sdp_ops_record_t */ */
int user2_ptr_len; /*!< see esp_bluetooth_sdp_ops_record_t */ typedef struct {
uint8_t *user2_ptr; /*!< see esp_bluetooth_sdp_ops_record_t */ esp_bluetooth_sdp_hdr_t hdr; /*!< General info */
} esp_bluetooth_sdp_hdr_overlay_t; 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 * @brief Message Access Profile - Server parameters
*/ */
typedef struct bluetooth_sdp_mas_record { typedef struct {
esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ esp_bluetooth_sdp_hdr_t hdr; /*!< General info */
uint32_t mas_instance_id; /*!< MAS Instance ID */ uint32_t mas_instance_id; /*!< MAS Instance ID */
uint32_t supported_features; /*!< Map supported features */ uint32_t supported_features; /*!< Map supported features */
uint32_t supported_message_types; /*!< Supported message types */ uint32_t supported_message_types; /*!< Supported message types */
} esp_bluetooth_sdp_mas_record_t; } esp_bluetooth_sdp_mas_record_t;
/** /**
* @brief Message Access Profile - Client (Notification Server) parameters * @brief Message Access Profile - Client (Notification Server) parameters
*/ */
typedef struct bluetooth_sdp_mns_record { typedef struct {
esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ esp_bluetooth_sdp_hdr_t hdr; /*!< General info */
uint32_t supported_features; /*!< Supported features */ uint32_t supported_features; /*!< Supported features */
} esp_bluetooth_sdp_mns_record_t; } esp_bluetooth_sdp_mns_record_t;
/** /**
* @brief Phone Book Profile - Server parameters * @brief Phone Book Profile - Server parameters
*/ */
typedef struct bluetooth_sdp_pse_record { typedef struct {
esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ esp_bluetooth_sdp_hdr_t hdr; /*!< General info */
uint32_t supported_features; /*!< Pbap Supported Features */ uint32_t supported_features; /*!< PBAP Supported Features */
uint32_t supported_repositories; /*!< Supported Repositories */ uint32_t supported_repositories; /*!< Supported Repositories */
} esp_bluetooth_sdp_pse_record_t; } esp_bluetooth_sdp_pse_record_t;
/** /**
* @brief Phone Book Profile - Client parameters * @brief Phone Book Profile - Client parameters
*/ */
typedef struct bluetooth_sdp_pce_record { typedef struct {
esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ esp_bluetooth_sdp_hdr_t hdr; /*!< General info */
} esp_bluetooth_sdp_pce_record_t; } esp_bluetooth_sdp_pce_record_t;
/** /**
* @brief Object Push Profile parameters * @brief Object Push Profile parameters
*/ */
typedef struct bluetooth_sdp_ops_record { typedef struct {
esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ esp_bluetooth_sdp_hdr_t hdr; /*!< General info */
int supported_formats_list_len; /*!< Supported formats list length */ int supported_formats_list_len; /*!< Supported formats list length */
uint8_t supported_formats_list[SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH]; /*!< Supported formats list */ uint8_t supported_formats_list[SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH]; /*!< Supported formats list */
} esp_bluetooth_sdp_ops_record_t; } esp_bluetooth_sdp_ops_record_t;
/** /**
* @brief SIM Access Profile parameters * @brief SIM Access Profile parameters
*/ */
typedef struct bluetooth_sdp_sap_record { typedef struct {
esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ esp_bluetooth_sdp_hdr_t hdr; /*!< General info */
} esp_bluetooth_sdp_sap_record_t; } 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 * @brief SDP record parameters union
*/ */
typedef union { typedef union {
esp_bluetooth_sdp_hdr_overlay_t hdr; /*!< General info */ esp_bluetooth_sdp_hdr_t hdr; /*!< General info */
esp_bluetooth_sdp_mas_record_t mas; /*!< Message Access Profile - Server */ esp_bluetooth_sdp_raw_record_t raw; /*!< Raw SDP search data for unknown UUIDs */
esp_bluetooth_sdp_mns_record_t mns; /*!< Message Access Profile - Client (Notification Server) */ esp_bluetooth_sdp_mas_record_t mas; /*!< Message Access Profile - Server */
esp_bluetooth_sdp_pse_record_t pse; /*!< Phone Book Profile - Server */ esp_bluetooth_sdp_mns_record_t mns; /*!< Message Access Profile - Client (Notification Server) */
esp_bluetooth_sdp_pce_record_t pce; /*!< Phone Book Profile - Client */ esp_bluetooth_sdp_pse_record_t pse; /*!< Phone Book Profile - Server */
esp_bluetooth_sdp_ops_record_t ops; /*!< Object Push Profile */ esp_bluetooth_sdp_pce_record_t pce; /*!< Phone Book Profile - Client */
esp_bluetooth_sdp_sap_record_t sap; /*!< SIM Access Profile */ 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; } esp_bluetooth_sdp_record_t;
/** /**
@ -141,44 +181,43 @@ typedef union {
* @brief ESP_SDP_INIT_EVT * @brief ESP_SDP_INIT_EVT
*/ */
struct sdp_init_evt_param { struct sdp_init_evt_param {
esp_sdp_status_t status; /*!< status */ esp_sdp_status_t status; /*!< Status */
} init; /*!< SDP callback param of ESP_SDP_INIT_EVT */ } init; /*!< SDP callback param of ESP_SDP_INIT_EVT */
/** /**
* @brief ESP_SDP_DEINIT_EVT * @brief ESP_SDP_DEINIT_EVT
*/ */
struct sdp_deinit_evt_param { struct sdp_deinit_evt_param {
esp_sdp_status_t status; /*!< status */ esp_sdp_status_t status; /*!< Status */
} deinit; /*!< SDP callback param of ESP_SDP_DEINIT_EVT */ } deinit; /*!< SDP callback param of ESP_SDP_DEINIT_EVT */
/** /**
* @brief ESP_SDP_SEARCH_COMP_EVT * @brief ESP_SDP_SEARCH_COMP_EVT
*/ */
struct sdp_search_evt_param { struct sdp_search_evt_param {
esp_sdp_status_t status; /*!< status */ esp_sdp_status_t status; /*!< Status */
esp_bd_addr_t remote_addr; /*!< remote device address */ esp_bd_addr_t remote_addr; /*!< Remote device address */
esp_bt_uuid_t sdp_uuid; /*!< service uuid */ esp_bt_uuid_t sdp_uuid; /*!< Service uuid */
int record_count; /*!< Number of SDP records */ int record_count; /*!< Number of SDP records */
esp_bluetooth_sdp_record_t *records;/*!< SDP records */ esp_bluetooth_sdp_record_t *records; /*!< SDP records */
} search; /*!< SDP callback param of ESP_SDP_SEARCH_COMP_EVT */ } search; /*!< SDP callback param of ESP_SDP_SEARCH_COMP_EVT */
/** /**
* @brief ESP_SDP_CREATE_RECORD_COMP_EVT * @brief ESP_SDP_CREATE_RECORD_COMP_EVT
*/ */
struct sdp_crate_record_evt_param { struct sdp_crate_record_evt_param {
esp_sdp_status_t status; /*!< status */ esp_sdp_status_t status; /*!< Status */
int record_handle; /*!< SDP record handle */ int record_handle; /*!< SDP record handle */
} create_record; /*!< SDP callback param of ESP_SDP_CREATE_RECORD_COMP_EVT */ } create_record; /*!< SDP callback param of ESP_SDP_CREATE_RECORD_COMP_EVT */
/** /**
* @brief ESP_SDP_REMOVE_RECORD_COMP_EVT * @brief ESP_SDP_REMOVE_RECORD_COMP_EVT
*/ */
struct sdp_remove_record_evt_param { struct sdp_remove_record_evt_param {
esp_sdp_status_t status; /*!< status */ esp_sdp_status_t status; /*!< Status */
} remove_record; /*!< SDP callback param of ESP_SDP_REMOVE_RECORD_COMP_EVT */ } remove_record; /*!< SDP callback param of ESP_SDP_REMOVE_RECORD_COMP_EVT */
} esp_sdp_cb_param_t; /*!< SDP callback parameter union type */
} esp_sdp_cb_param_t;
/** /**
* @brief SDP callback function type. * @brief SDP callback function type.

View File

@ -29,6 +29,7 @@
#include "stack/btm_api.h" #include "stack/btm_api.h"
#include "btm_int.h" #include "btm_int.h"
#include <string.h> #include <string.h>
#include <assert.h>
#include "bta/utl.h" #include "bta/utl.h"
#include "osi/allocator.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, tBTA_STATUS BTA_DmSetLocalDiRecord( tBTA_DI_RECORD *p_device_info,
UINT32 *p_handle ) 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 (bta_dm_di_cb.di_num < BTA_DI_NUM_MAX) {
if (SDP_SetLocalDiRecord((tSDP_DI_RECORD *)p_device_info, p_handle) == SDP_SUCCESS) { if (SDP_SetLocalDiRecord((tSDP_DI_RECORD *)p_device_info, p_handle) == SDP_SUCCESS) {
if (!p_device_info->primary_record) { if (!p_device_info->primary_record) {
bta_dm_di_cb.di_handle[bta_dm_di_cb.di_num] = *p_handle; for (uint8_t i = 1; i < BTA_DI_NUM_MAX; i++) {
bta_dm_di_cb.di_num ++; 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); if (!bta_dm_di_cb.uuid_added) {
status = BTA_SUCCESS; bta_sys_add_uuid(UUID_SERVCLASS_PNP_INFORMATION);
bta_dm_di_cb.uuid_added = TRUE;
}
status = BTA_SUCCESS;
} }
} }
return status; 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 #endif ///SDP_INCLUDED == TRUE
/******************************************************************************* /*******************************************************************************
** **

View File

@ -1590,6 +1590,7 @@ typedef struct {
#if (SDP_INCLUDED == TRUE) #if (SDP_INCLUDED == TRUE)
tSDP_DISCOVERY_DB *p_di_db; /* pointer to the DI discovery database */ tSDP_DISCOVERY_DB *p_di_db; /* pointer to the DI discovery database */
#endif ///SDP_INCLUDED == TRUE #endif ///SDP_INCLUDED == TRUE
BOOLEAN uuid_added;
UINT8 di_num; /* total local DI record number */ 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 */ UINT32 di_handle[BTA_DI_NUM_MAX]; /* local DI record handle, the first one is primary record */
} tBTA_DM_DI_CB; } tBTA_DM_DI_CB;

View File

@ -2190,6 +2190,17 @@ extern UINT16 BTA_DmGetConnectionState( BD_ADDR bd_addr );
*******************************************************************************/ *******************************************************************************/
extern tBTA_STATUS BTA_DmSetLocalDiRecord( tBTA_DI_RECORD *p_device_info, extern tBTA_STATUS BTA_DmSetLocalDiRecord( tBTA_DI_RECORD *p_device_info,
UINT32 *p_handle ); 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 #endif ///SDP_INCLUDED == TRUE
/******************************************************************************* /*******************************************************************************
** **

View File

@ -41,7 +41,7 @@ typedef UINT8 tBTA_SDP_STATUS;
/* SDP I/F callback events */ /* SDP I/F callback events */
/* events received by tBTA_SDP_DM_CBACK */ /* events received by tBTA_SDP_DM_CBACK */
#define BTA_SDP_ENABLE_EVT 0 /* SDP service enabled */ #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_EVT 2 /* SDP search started */
#define BTA_SDP_SEARCH_COMP_EVT 3 /* SDP search complete */ #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_CREATE_RECORD_USER_EVT 4 /* SDP create record complete */
@ -67,10 +67,17 @@ typedef struct {
int handle; int handle;
} tBTA_SDP_CREATE_RECORD_USER; } 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 { typedef union {
tBTA_SDP_STATUS status; /* BTA_SDP_SEARCH_EVT */ tBTA_SDP_STATUS status; /* BTA_SDP_SEARCH_EVT */
tBTA_SDP_SEARCH_COMP sdp_search_comp; /* BTA_SDP_SEARCH_COMP_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_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; } tBTA_SDP;
/* SDP DM Interface callback */ /* SDP DM Interface callback */
@ -108,14 +115,28 @@ extern tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK *p_cback);
** **
** Function BTA_SdpDisable ** 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. ** Free buffer for SDP configuration structure.
** **
** Returns BTA_SDP_SUCCESS if successful. ** Returns BTA_SDP_SUCCESS if successful.
** BTA_SDP_FAIL if internal failure. ** BTA_SDP_FAIL if internal failure.
** **
*******************************************************************************/ *******************************************************************************/
extern tBTA_SDP_STATUS BTA_SdpDisable(void); extern tBTA_SDP_STATUS BTA_SdpCleanup(void);
/******************************************************************************* /*******************************************************************************
** **

View File

@ -49,10 +49,11 @@ typedef void (*tBTA_SDP_ACTION)(tBTA_SDP_MSG *p_data);
/* action function list */ /* action function list */
const tBTA_SDP_ACTION bta_sdp_action[] = { const tBTA_SDP_ACTION bta_sdp_action[] = {
bta_sdp_enable, /* BTA_SDP_API_ENABLE_EVT */ bta_sdp_enable, /* BTA_SDP_API_ENABLE_EVT */
bta_sdp_search, /* BTA_SDP_API_SEARCH_EVT */ bta_sdp_search, /* BTA_SDP_API_SEARCH_EVT */
bta_sdp_create_record, /* BTA_SDP_API_CREATE_RECORD_USER_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_remove_record, /* BTA_SDP_API_REMOVE_RECORD_USER_EVT */
bta_sdp_disable, /* BTA_SDP_API_DISABLE_EVT */
}; };
/******************************************************************************* /*******************************************************************************

View File

@ -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) static void bta_create_mas_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
{ {
tSDP_DISC_ATTR *p_attr; 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)) { if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
record->pse.hdr.rfcomm_channel_number = pe.params[0]; record->pse.hdr.rfcomm_channel_number = pe.params[0];
} }
record->hdr.user1_ptr_len = p_bta_sdp_cfg->p_sdp_db->raw_size; record->raw.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 = 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 */ /* generate the matching record data pointer */
if (p_rec != NULL) { if (p_rec != NULL) {
status = BTA_SDP_SUCCESS; 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__); APPL_TRACE_DEBUG("%s() - found MAP (MAS) uuid\n", __func__);
bta_create_mas_sdp_record(&evt_data.records[count], p_rec); bta_create_mas_sdp_record(&evt_data.records[count], p_rec);
} else if (IS_UUID(UUID_MAP_MNS, uuid->uu.uuid128)) { } else if (IS_UUID(UUID_MAP_MNS, uuid->uu.uuid128)) {
@ -558,7 +602,7 @@ void bta_sdp_create_record(tBTA_SDP_MSG *p_data)
APPL_TRACE_DEBUG("%s() event: %d\n", __func__, p_data->record.hdr.event); APPL_TRACE_DEBUG("%s() event: %d\n", __func__, p_data->record.hdr.event);
tBTA_SDP_CREATE_RECORD_USER bta_sdp = {0}; tBTA_SDP_CREATE_RECORD_USER bta_sdp = {0};
bta_sdp.status = BTA_SDP_SUCCESS; bta_sdp.status = BTA_SDP_SUCCESS;
bta_sdp.handle = (int)p_data->record.user_data; bta_sdp.handle = -1;
if (bta_sdp_cb.p_dm_cback) { if (bta_sdp_cb.p_dm_cback) {
bta_sdp_cb.p_dm_cback(BTA_SDP_CREATE_RECORD_USER_EVT, (tBTA_SDP *)&bta_sdp, p_data->record.user_data); bta_sdp_cb.p_dm_cback(BTA_SDP_CREATE_RECORD_USER_EVT, (tBTA_SDP *)&bta_sdp, p_data->record.user_data);
} }
@ -576,10 +620,30 @@ void bta_sdp_create_record(tBTA_SDP_MSG *p_data)
void bta_sdp_remove_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); 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; tBTA_SDP bta_sdp;
bta_sdp.status = BTA_SDP_SUCCESS; bta_sdp.status = BTA_SDP_SUCCESS;
if (bta_sdp_cb.p_dm_cback) { 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);
} }
} }

View File

@ -101,15 +101,27 @@ tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK *p_cback)
*******************************************************************************/ *******************************************************************************/
tBTA_SDP_STATUS BTA_SdpDisable(void) tBTA_SDP_STATUS BTA_SdpDisable(void)
{ {
BT_HDR *p_buf = NULL;
tBTA_SDP_STATUS status = BTA_SDP_SUCCESS; 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); bta_sys_deregister(BTA_ID_SDP);
#if BTA_DYNAMIC_MEMORY == TRUE #if BTA_DYNAMIC_MEMORY == TRUE
/* Free buffer for SDP configuration structure */ /* Free buffer for SDP configuration structure */
osi_free(p_bta_sdp_cfg->p_sdp_db); osi_free(p_bta_sdp_cfg->p_sdp_db);
p_bta_sdp_cfg->p_sdp_db = NULL; p_bta_sdp_cfg->p_sdp_db = NULL;
#endif #endif
return (status); return BTA_SDP_SUCCESS;
} }
/******************************************************************************* /*******************************************************************************

View File

@ -42,6 +42,7 @@ enum {
BTA_SDP_API_SEARCH_EVT, BTA_SDP_API_SEARCH_EVT,
BTA_SDP_API_CREATE_RECORD_USER_EVT, BTA_SDP_API_CREATE_RECORD_USER_EVT,
BTA_SDP_API_REMOVE_RECORD_USER_EVT, BTA_SDP_API_REMOVE_RECORD_USER_EVT,
BTA_SDP_API_DISABLE_EVT,
BTA_SDP_MAX_INT_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_search (tBTA_SDP_MSG *p_data);
extern void bta_sdp_create_record(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_remove_record(tBTA_SDP_MSG *p_data);
extern void bta_sdp_disable(tBTA_SDP_MSG *p_data);
#endif ///SDP_INCLUDED == TRUE #endif ///SDP_INCLUDED == TRUE

View File

@ -34,79 +34,77 @@ typedef enum {
SDP_TYPE_PBAP_PSE, // Phone Book Profile - Server SDP_TYPE_PBAP_PSE, // Phone Book Profile - Server
SDP_TYPE_PBAP_PCE, // Phone Book Profile - Client SDP_TYPE_PBAP_PCE, // Phone Book Profile - Client
SDP_TYPE_OPP_SERVER, // Object Push Profile 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; } bluetooth_sdp_types;
typedef struct _bluetooth_sdp_hdr { typedef struct _bluetooth_sdp_hdr {
bluetooth_sdp_types type; bluetooth_sdp_types type;
esp_bt_uuid_t uuid; uint32_t service_name_length;
uint32_t service_name_length; char *service_name;
char *service_name; int32_t rfcomm_channel_number;
int32_t rfcomm_channel_number; int32_t l2cap_psm;
int32_t l2cap_psm; int32_t profile_version;
int32_t profile_version;
} bluetooth_sdp_hdr; } bluetooth_sdp_hdr;
/** typedef struct _bluetooth_sdp_raw_record {
* Some signals need additional pointers, hence we introduce a bluetooth_sdp_hdr hdr;
* generic way to handle these pointers. esp_bt_uuid_t uuid;
*/ int user1_ptr_len;
typedef struct _bluetooth_sdp_hdr_overlay { uint8_t *user1_ptr;
bluetooth_sdp_types type; } bluetooth_sdp_raw_record;
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_mas_record { typedef struct _bluetooth_sdp_mas_record {
bluetooth_sdp_hdr_overlay hdr; bluetooth_sdp_hdr hdr;
uint32_t mas_instance_id; uint32_t mas_instance_id;
uint32_t supported_features; uint32_t supported_features;
uint32_t supported_message_types; uint32_t supported_message_types;
} bluetooth_sdp_mas_record; } bluetooth_sdp_mas_record;
typedef struct _bluetooth_sdp_mns_record { typedef struct _bluetooth_sdp_mns_record {
bluetooth_sdp_hdr_overlay hdr; bluetooth_sdp_hdr hdr;
uint32_t supported_features; uint32_t supported_features;
} bluetooth_sdp_mns_record; } bluetooth_sdp_mns_record;
typedef struct _bluetooth_sdp_pse_record { typedef struct _bluetooth_sdp_pse_record {
bluetooth_sdp_hdr_overlay hdr; bluetooth_sdp_hdr hdr;
uint32_t supported_features; uint32_t supported_features;
uint32_t supported_repositories; uint32_t supported_repositories;
} bluetooth_sdp_pse_record; } bluetooth_sdp_pse_record;
typedef struct _bluetooth_sdp_pce_record { typedef struct _bluetooth_sdp_pce_record {
bluetooth_sdp_hdr_overlay hdr; bluetooth_sdp_hdr hdr;
} bluetooth_sdp_pce_record; } bluetooth_sdp_pce_record;
typedef struct _bluetooth_sdp_ops_record { typedef struct _bluetooth_sdp_ops_record {
bluetooth_sdp_hdr_overlay hdr; bluetooth_sdp_hdr hdr;
int supported_formats_list_len; int supported_formats_list_len;
uint8_t supported_formats_list[SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH]; uint8_t supported_formats_list[SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH];
} bluetooth_sdp_ops_record; } bluetooth_sdp_ops_record;
typedef struct _bluetooth_sdp_sap_record { typedef struct _bluetooth_sdp_sap_record {
bluetooth_sdp_hdr_overlay hdr; bluetooth_sdp_hdr hdr;
} bluetooth_sdp_sap_record; } 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 { typedef union {
bluetooth_sdp_hdr_overlay hdr; bluetooth_sdp_hdr hdr;
bluetooth_sdp_mas_record mas; bluetooth_sdp_raw_record raw;
bluetooth_sdp_mns_record mns; bluetooth_sdp_mas_record mas;
bluetooth_sdp_pse_record pse; bluetooth_sdp_mns_record mns;
bluetooth_sdp_pce_record pce; bluetooth_sdp_pse_record pse;
bluetooth_sdp_ops_record ops; bluetooth_sdp_pce_record pce;
bluetooth_sdp_sap_record sap; bluetooth_sdp_ops_record ops;
bluetooth_sdp_sap_record sap;
bluetooth_sdp_dip_record dip;
} bluetooth_sdp_record; } bluetooth_sdp_record;
#endif /* __BT_SDP_H__ */ #endif /* __BT_SDP_H__ */

View File

@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -13,7 +13,7 @@
#include "bta/bta_sdp_api.h" #include "bta/bta_sdp_api.h"
#include "bt_sdp.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 { typedef enum {
BTC_SDP_ACT_INIT = 0, BTC_SDP_ACT_INIT = 0,
@ -32,9 +32,9 @@ typedef union {
} search; } search;
//BTC_SDP_ACT_CREATE_RECORD //BTC_SDP_ACT_CREATE_RECORD
struct creat_record_arg { struct create_record_arg {
bluetooth_sdp_record *record; bluetooth_sdp_record *record;
} creat_record; } create_record;
//BTC_SDP_ACT_REMOVE_RECORD //BTC_SDP_ACT_REMOVE_RECORD
struct remove_record_arg { 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_call_handler(btc_msg_t *msg);
void btc_sdp_cb_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__ #endif ///__BTC_SDP_H__

View File

@ -17,7 +17,7 @@
#include "osi/allocator.h" #include "osi/allocator.h"
#include "esp_sdp_api.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 { typedef enum {
SDP_RECORD_FREE = 0, SDP_RECORD_FREE = 0,
@ -25,12 +25,21 @@ typedef enum {
} sdp_state_t; } sdp_state_t;
typedef struct { 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; int sdp_handle;
bluetooth_sdp_record* record_data; esp_bt_uuid_t uuid;
void* record_data;
} sdp_slot_t; } sdp_slot_t;
typedef struct { typedef struct {
bool search_allowed;
sdp_slot_t *sdp_slots[SDP_MAX_RECORDS]; sdp_slot_t *sdp_slots[SDP_MAX_RECORDS];
osi_mutex_t sdp_slot_mutex; osi_mutex_t sdp_slot_mutex;
} sdp_local_param_t; } sdp_local_param_t;
@ -48,6 +57,21 @@ static sdp_local_param_t *sdp_local_param_ptr;
#define is_sdp_init() (&sdp_local_param != NULL && sdp_local_param.sdp_slot_mutex != NULL) #define is_sdp_init() (&sdp_local_param != NULL && sdp_local_param.sdp_slot_mutex != NULL)
#endif #endif
static void btc_sdp_cleanup(void)
{
#if SDP_DYNAMIC_MEMORY == TRUE
if (sdp_local_param_ptr) {
#endif
if (sdp_local_param.sdp_slot_mutex) {
osi_mutex_free(&sdp_local_param.sdp_slot_mutex);
sdp_local_param.sdp_slot_mutex = NULL;
}
#if SDP_DYNAMIC_MEMORY == TRUE
osi_free(sdp_local_param_ptr);
sdp_local_param_ptr = NULL;
}
#endif
}
static inline void btc_sdp_cb_to_app(esp_sdp_cb_event_t event, esp_sdp_cb_param_t *param) static inline void btc_sdp_cb_to_app(esp_sdp_cb_event_t event, esp_sdp_cb_param_t *param)
{ {
@ -57,46 +81,38 @@ 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; bluetooth_sdp_record *record = in_record;
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;
int records_size = 0; int records_size = 0;
for(int i = 0; i < count; i++) { switch (record->hdr.type) {
record = &in_record[i]; 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 += sizeof(bluetooth_sdp_record);
records_size += record->hdr.service_name_length; 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++; /* + '\0' termination of string */
} }
records_size += record->hdr.user1_ptr_len; break;
records_size += record->hdr.user2_ptr_len;
} }
return records_size; return records_size;
} }
static void set_sdp_handle(int id, int handle) static void set_sdp_slot_info(int id, int sdp_handle, esp_bt_uuid_t *uuid)
{ {
sdp_slot_t *slot = NULL; sdp_slot_t *slot = NULL;
BTC_TRACE_DEBUG("%s() id=%d to handle=0x%08x", __func__, id, handle); BTC_TRACE_DEBUG("%s() id=%d to sdp_handle=0x%08x", __func__, id, sdp_handle);
if(id >= SDP_MAX_RECORDS) { if(id >= SDP_MAX_RECORDS) {
BTC_TRACE_ERROR("%s() failed - id %d is invalid", __func__, id); BTC_TRACE_ERROR("%s() failed - id %d is invalid", __func__, id);
@ -104,34 +120,68 @@ static void set_sdp_handle(int id, int handle)
} }
osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
slot = sdp_local_param.sdp_slots[id];
if (slot == NULL) { do {
osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); slot = sdp_local_param.sdp_slots[id];
BTC_TRACE_ERROR("%s() id=%d to handle=0x%08x, set failed", __func__, id, handle); if (slot == NULL) {
return; BTC_TRACE_ERROR("%s() id = %d ", __func__, id);
} break;
slot->sdp_handle = handle; }
if (slot->state != SDP_RECORD_ALLOCED) {
BTC_TRACE_ERROR("%s() failed - state for id %d is state = %d expected %d", __func__, id,
sdp_local_param.sdp_slots[id]->state, SDP_RECORD_ALLOCED);
break;
}
slot->sdp_handle = sdp_handle;
slot->record_data = NULL;
if (uuid) {
memcpy(&slot->uuid, uuid, sizeof(esp_bt_uuid_t));
} else {
memset(&slot->uuid, 0, sizeof(esp_bt_uuid_t));
}
} while (0);
osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
} }
static void get_sdp_slot_info(int id, int *sdp_handle, esp_bt_uuid_t *uuid, sdp_flag_t *flag)
static bool get_sdp_record_by_handle(int handle, bluetooth_sdp_record* record)
{ {
sdp_slot_t *slot = NULL; sdp_slot_t *slot = NULL;
osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); if(id >= SDP_MAX_RECORDS) {
BTC_TRACE_ERROR("%s() failed - id %d is invalid", __func__, id);
for (int i = 0; i < SDP_MAX_RECORDS; i++) { return;
slot = sdp_local_param.sdp_slots[i];
if ((slot != NULL) && (slot->sdp_handle == handle)) {
memcpy(record, slot->record_data, sizeof(bluetooth_sdp_record));
osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
return true;
}
} }
osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
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); osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
return false;
} }
static int get_sdp_slot_id_by_handle(int handle) static int get_sdp_slot_id_by_handle(int handle)
@ -152,9 +202,10 @@ static int get_sdp_slot_id_by_handle(int handle)
return -1; return -1;
} }
static sdp_slot_t *start_create_sdp(int id) static bluetooth_sdp_record *start_create_sdp(int id)
{ {
sdp_slot_t *sdp_slot = NULL; sdp_slot_t *slot = NULL;
bluetooth_sdp_record* record_data = NULL;
if(id >= SDP_MAX_RECORDS) { if(id >= SDP_MAX_RECORDS) {
BTC_TRACE_ERROR("%s() failed - id %d is invalid", __func__, id); BTC_TRACE_ERROR("%s() failed - id %d is invalid", __func__, id);
@ -162,64 +213,94 @@ static sdp_slot_t *start_create_sdp(int id)
} }
osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); 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) { do {
BTC_TRACE_ERROR("%s() id = %d ", __func__, id); slot = sdp_local_param.sdp_slots[id];
} else if(sdp_slot->state != SDP_RECORD_ALLOCED) { if (slot == NULL) {
BTC_TRACE_ERROR("%s() failed - state for id %d is state = %d expected %d", __func__, BTC_TRACE_ERROR("%s() id = %d ", __func__, id);
id, sdp_local_param.sdp_slots[id]->state, SDP_RECORD_ALLOCED); break;
/* The record have been removed before this event occurred - e.g. deinit */ }
sdp_slot = NULL;
} if (slot->state != SDP_RECORD_ALLOCED) {
BTC_TRACE_ERROR("%s() failed - state for id %d is state = %d expected %d", __func__, id,
sdp_local_param.sdp_slots[id]->state, SDP_RECORD_ALLOCED);
break;
}
record_data = slot->record_data;
} while (0);
osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
return sdp_slot; return record_data;
} }
/* Deep copy all content of in_records into out_records. /* Deep copy all content of in_records into out_records.
* out_records must point to a chunk of memory large enough to contain all * out_records must point to a chunk of memory large enough to contain all
* the data. Use getSdpRecordsSize() to calculate the needed size. */ * 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; uint8_t *free_ptr = (uint8_t *)(out_record + 1); /* set pointer to after the last entry */
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++) { memcpy(out_record, in_record, sizeof(bluetooth_sdp_record));
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) { 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 = NULL;
out_record->hdr.service_name_length = 0; out_record->hdr.service_name_length = 0;
} else { } else {
out_record->hdr.service_name = free_ptr; // Update service_name pointer out_record->hdr.service_name = (char *)free_ptr; // Update service_name pointer
// Copy string // Copy string
memcpy(free_ptr, in_record->hdr.service_name, in_record->hdr.service_name_length); memcpy(free_ptr, in_record->hdr.service_name, in_record->hdr.service_name_length);
free_ptr += in_record->hdr.service_name_length; free_ptr += in_record->hdr.service_name_length;
*(free_ptr) = '\0'; // Set '\0' termination of string *(free_ptr) = '\0'; // Set '\0' termination of string
free_ptr++; 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.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) static int alloc_sdp_slot(bluetooth_sdp_record* in_record)
{ {
int i; 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; bluetooth_sdp_record *record = NULL;
sdp_slot_t **slot = 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); record = osi_malloc(record_size);
if (record == NULL) { if (record == NULL) {
@ -227,22 +308,42 @@ static int alloc_sdp_slot(bluetooth_sdp_record* in_record)
return -1; 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); osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
for(i = 0; i < SDP_MAX_RECORDS; i++) // find the primary di record slot
{ if (is_di_record && is_primary_di_record) {
slot = &sdp_local_param.sdp_slots[i]; for (i = 0; i < SDP_MAX_RECORDS; i++) {
if ((*slot) == NULL) { slot = &sdp_local_param.sdp_slots[i];
if (((*slot) = (sdp_slot_t *)osi_malloc(sizeof(sdp_slot_t))) == NULL) { if ((*slot) && (*slot)->flag.di && (*slot)->flag.primary_di) {
osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); BTC_TRACE_WARNING("%s() overwrite primary di record!", __func__);
BTC_TRACE_ERROR("%s() osi_malloc slot failed!", __func__); if ((*slot)->record_data) {
osi_free(record); osi_free((*slot)->record_data);
return -1; }
(*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); osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
@ -292,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 */ /* 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]; tSDP_PROTOCOL_ELEM protoList [2];
UINT16 browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP; UINT16 browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
@ -310,15 +411,15 @@ static int add_raw_sdp(const bluetooth_sdp_record* rec)
return sdp_handle; 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); 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); UINT16_TO_BE_STREAM (p_temp, rec->uuid.uuid.uuid16);
} else if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_32) { } else if (rec->uuid.len == ESP_UUID_LEN_32) {
UINT8_TO_BE_STREAM (p_temp, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES); 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); UINT32_TO_BE_STREAM (p_temp, rec->uuid.uuid.uuid32);
} else if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_128) { } else if (rec->uuid.len == ESP_UUID_LEN_128) {
UINT8_TO_BE_STREAM (p_temp, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES); 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 { } else {
SDP_DeleteRecord(sdp_handle); SDP_DeleteRecord(sdp_handle);
sdp_handle = 0; sdp_handle = 0;
@ -357,7 +458,7 @@ static int add_raw_sdp(const bluetooth_sdp_record* rec)
UINT_DESC_TYPE, (UINT32)2, temp); UINT_DESC_TYPE, (UINT32)2, temp);
} }
/* Make the service browseable */ /* Make the service browsable */
status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
if (!status) { if (!status) {
@ -365,12 +466,12 @@ static int add_raw_sdp(const bluetooth_sdp_record* rec)
sdp_handle = 0; sdp_handle = 0;
BTC_TRACE_ERROR("%s() FAILED, status = %d", __func__, status); BTC_TRACE_ERROR("%s() FAILED, status = %d", __func__, status);
} else { } else {
if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_16) { if (rec->uuid.len == ESP_UUID_LEN_16) {
bta_sys_add_uuid(rec->hdr.bt_uuid.uuid.uuid16); bta_sys_add_uuid(rec->uuid.uuid.uuid16);
} else if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_32) { } else if (rec->uuid.len == ESP_UUID_LEN_32) {
bta_sys_add_uuid_32(rec->hdr.bt_uuid.uuid.uuid32); bta_sys_add_uuid_32(rec->uuid.uuid.uuid32);
} else if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_128) { } else if (rec->uuid.len == ESP_UUID_LEN_128) {
bta_sys_add_uuid_128((UINT8 *)&rec->hdr.bt_uuid.uuid.uuid128); bta_sys_add_uuid_128((UINT8 *)&rec->uuid.uuid.uuid128);
} }
BTC_TRACE_DEBUG("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle); BTC_TRACE_DEBUG("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle);
} }
@ -448,7 +549,7 @@ static int add_maps_sdp(const bluetooth_sdp_mas_record* rec)
UINT_DESC_TYPE, (UINT32)2, temp); UINT_DESC_TYPE, (UINT32)2, temp);
} }
/* Make the service browseable */ /* Make the service browsable */
status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
if (!status) { if (!status) {
@ -523,7 +624,7 @@ static int add_mapc_sdp(const bluetooth_sdp_mns_record* rec)
UINT_DESC_TYPE, (UINT32)2, temp); UINT_DESC_TYPE, (UINT32)2, temp);
} }
/* Make the service browseable */ /* Make the service browsable */
status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
if (!status) { if (!status) {
@ -603,7 +704,7 @@ static int add_pbaps_sdp(const bluetooth_sdp_pse_record* rec)
UINT_DESC_TYPE, (UINT32)2, temp); UINT_DESC_TYPE, (UINT32)2, temp);
} }
/* Make the service browseable */ /* Make the service browsable */
status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
if (!status) { if (!status) {
@ -649,7 +750,7 @@ static int add_pbapc_sdp(const bluetooth_sdp_pce_record* rec)
UUID_SERVCLASS_PHONE_ACCESS, UUID_SERVCLASS_PHONE_ACCESS,
rec->hdr.profile_version); rec->hdr.profile_version);
/* Make the service browseable */ /* Make the service browsable */
status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
if (!status) { if (!status) {
@ -736,7 +837,7 @@ static int add_opps_sdp(const bluetooth_sdp_ops_record* rec)
UINT_DESC_TYPE, (UINT32)2, temp); UINT_DESC_TYPE, (UINT32)2, temp);
} }
/* Make the service browseable */ /* Make the service browsable */
status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
if (!status) { if (!status) {
@ -799,7 +900,7 @@ static int add_saps_sdp(const bluetooth_sdp_sap_record* rec)
UUID_SERVCLASS_SAP, UUID_SERVCLASS_SAP,
rec->hdr.profile_version); rec->hdr.profile_version);
// Make the service browseable // Make the service browsable
status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
if (!status) { if (!status) {
@ -814,60 +915,126 @@ static int add_saps_sdp(const bluetooth_sdp_sap_record* rec)
return sdp_handle; return sdp_handle;
} }
static int btc_handle_create_record_event(int id) static int add_dips_sdp(bluetooth_sdp_dip_record *rec)
{ {
int handle = -1; UINT32 sdp_handle = 0;
const sdp_slot_t *sdp_slot = NULL; tBTA_DI_RECORD device_info = {0};
BTC_TRACE_DEBUG("Sdp Server %s", __func__); 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;
sdp_slot = start_create_sdp(id); BTA_DmSetLocalDiRecord(&device_info, &sdp_handle);
if(sdp_slot != NULL) {
bluetooth_sdp_record* record = sdp_slot->record_data;
switch(record->hdr.type) {
case SDP_TYPE_RAW:
handle = add_raw_sdp(record);
break;
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_PBAP_PCE:
handle = add_pbapc_sdp(&record->pce);
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;
default:
BTC_TRACE_DEBUG("Record type %d is not supported",record->hdr.type);
break;
}
if(handle != -1) {
set_sdp_handle(id, handle);
}
}
return handle; return sdp_handle;
} }
static bool btc_sdp_remove_record_event(int handle) static int btc_handle_create_record_event(int id)
{ {
bool result = false; 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__); BTC_TRACE_DEBUG("Sdp Server %s", __func__);
if(handle != -1 && handle != 0) { if (record != NULL) {
result = SDP_DeleteRecord(handle); switch (record->hdr.type) {
if(result == false) { case SDP_TYPE_RAW:
BTC_TRACE_ERROR(" Unable to remove handle 0x%08x", handle); 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);
break;
}
if(sdp_handle != 0) {
set_sdp_slot_info(id, sdp_handle, &service_uuid);
// free the record, since not use it anymore
osi_free(record);
} else {
sdp_handle = -1;
}
} else {
sdp_handle = -1;
}
if (sdp_handle == -1) {
free_sdp_slot(id);
}
return sdp_handle;
}
static bool btc_sdp_remove_record_event(int id, int *p_sdp_handle)
{
BTC_TRACE_DEBUG("Sdp Server %s", __func__);
bool result = false;
int sdp_handle = -1;
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;
} }
} }
@ -881,18 +1048,18 @@ static void btc_sdp_dm_cback(tBTA_SDP_EVT event, tBTA_SDP* p_data, void* user_da
switch (event) { switch (event) {
case BTA_SDP_CREATE_RECORD_USER_EVT: { 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); p_data->sdp_create_record.handle = btc_handle_create_record_event((int)user_data);
if (p_data->sdp_create_record.handle < 0) { if (p_data->sdp_create_record.handle < 0) {
p_data->status = BTA_SDP_FAILURE; p_data->sdp_create_record.status = BTA_SDP_FAILURE;
} }
} }
} }
break; break;
case BTA_SDP_REMOVE_RECORD_USER_EVT: { case BTA_SDP_REMOVE_RECORD_USER_EVT: {
if (p_data->status == BTA_SDP_SUCCESS) { if (p_data->sdp_remove_record.status == BTA_SDP_SUCCESS) {
if (btc_sdp_remove_record_event((int)user_data) == false) { if (btc_sdp_remove_record_event((int)user_data, &p_data->sdp_remove_record.handle) == false) {
p_data->status = BTA_SDP_FAILURE; p_data->sdp_remove_record.status = BTA_SDP_FAILURE;
} }
} }
} }
@ -930,23 +1097,27 @@ static void btc_sdp_init(void)
ret = ESP_SDP_NO_RESOURCE; ret = ESP_SDP_NO_RESOURCE;
break; break;
} }
memset((void *)sdp_local_param_ptr, 0, sizeof(sdp_local_param_t));
#endif #endif
memset(&sdp_local_param, 0, sizeof(sdp_local_param_t));
if (osi_mutex_new(&sdp_local_param.sdp_slot_mutex) != 0) { 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__); BTC_TRACE_ERROR("%s osi_mutex_new failed\n", __func__);
ret = ESP_SDP_NO_RESOURCE; ret = ESP_SDP_NO_RESOURCE;
break; break;
} }
ret = BTA_SdpEnable(btc_sdp_dm_cback); ret = BTA_SdpEnable(btc_sdp_dm_cback);
if (ret != ESP_SDP_SUCCESS) {
BTC_TRACE_ERROR("%s BTA_SdpEnable failed, ret = %d\n", __func__, ret);
ret = ESP_SDP_FAILURE;
break;
}
sdp_local_param.search_allowed = true;
} while(0); } while(0);
if (ret != ESP_SDP_SUCCESS) { if (ret != ESP_SDP_SUCCESS) {
btc_sdp_cleanup();
param.init.status = ret; param.init.status = ret;
btc_sdp_cb_to_app(ESP_SDP_INIT_EVT, &param); btc_sdp_cb_to_app(ESP_SDP_INIT_EVT, &param);
} }
@ -956,7 +1127,6 @@ static void btc_sdp_deinit(void)
{ {
esp_sdp_cb_param_t param; esp_sdp_cb_param_t param;
esp_sdp_status_t ret = ESP_SDP_SUCCESS; esp_sdp_status_t ret = ESP_SDP_SUCCESS;
int handle;
do { do {
if (!is_sdp_init()) { if (!is_sdp_init()) {
@ -966,12 +1136,13 @@ static void btc_sdp_deinit(void)
} }
for(int i = 0; i < SDP_MAX_RECORDS; i++) { for(int i = 0; i < SDP_MAX_RECORDS; i++) {
handle = free_sdp_slot(i); int sdp_handle = -1;
if (handle > 0) { get_sdp_slot_info(i, &sdp_handle, NULL, NULL);
BTA_SdpRemoveRecordByUser((void*)handle); if (sdp_handle > 0) {
BTA_SdpRemoveRecordByUser((void*)i);
} }
} }
sdp_disable_handler(); BTA_SdpDisable();
} while(0); } while(0);
if (ret != ESP_SDP_SUCCESS) { if (ret != ESP_SDP_SUCCESS) {
@ -982,7 +1153,7 @@ static void btc_sdp_deinit(void)
static void btc_sdp_create_record(btc_sdp_args_t *arg) static void btc_sdp_create_record(btc_sdp_args_t *arg)
{ {
int handle; int slot_id;
esp_sdp_cb_param_t param; esp_sdp_cb_param_t param;
esp_sdp_status_t ret = ESP_SDP_SUCCESS; esp_sdp_status_t ret = ESP_SDP_SUCCESS;
@ -993,13 +1164,13 @@ static void btc_sdp_create_record(btc_sdp_args_t *arg)
break; break;
} }
handle = alloc_sdp_slot(arg->creat_record.record); slot_id = alloc_sdp_slot(arg->create_record.record);
if (handle < 0) { if (slot_id < 0) {
ret = ESP_SDP_FAILURE; ret = ESP_SDP_FAILURE;
break; break;
} }
BTA_SdpCreateRecordByUser((void *) handle); BTA_SdpCreateRecordByUser((void *) slot_id);
} while(0); } while(0);
if (ret != ESP_SDP_SUCCESS) { if (ret != ESP_SDP_SUCCESS) {
@ -1011,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) static void btc_sdp_remove_record(btc_sdp_args_t *arg)
{ {
int handle;
esp_sdp_cb_param_t param; esp_sdp_cb_param_t param;
esp_sdp_status_t ret = ESP_SDP_SUCCESS; esp_sdp_status_t ret = ESP_SDP_SUCCESS;
@ -1022,42 +1192,16 @@ static void btc_sdp_remove_record(btc_sdp_args_t *arg)
break; break;
} }
bluetooth_sdp_record rec;
if (get_sdp_record_by_handle(arg->remove_record.record_handle, &rec)) {
if (rec.hdr.bt_uuid.len == ESP_UUID_LEN_16) {
bta_sys_remove_uuid(rec.hdr.bt_uuid.uuid.uuid16);
} else if (rec.hdr.bt_uuid.len == ESP_UUID_LEN_32) {
bta_sys_remove_uuid_32(rec.hdr.bt_uuid.uuid.uuid32);
} else if (rec.hdr.bt_uuid.len == ESP_UUID_LEN_128) {
bta_sys_remove_uuid_128((UINT8 *)&rec.hdr.bt_uuid.uuid.uuid128);
}
} else {
BTC_TRACE_ERROR("%s SDP record with handle %d not found",
__func__, arg->remove_record.record_handle);
ret = ESP_SDP_NO_CREATE_RECORD;
break;
}
/* Get the Record handle, and free the slot */ /* Get the Record handle, and free the slot */
/* The application layer record_handle is equivalent to the id of the btc layer */ /* 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); int slot_id = get_sdp_slot_id_by_handle(arg->remove_record.record_handle);
if (slot < 0) { 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; ret = ESP_SDP_NO_CREATE_RECORD;
break; break;
} }
handle = free_sdp_slot(slot); BTA_SdpRemoveRecordByUser((void *)slot_id);
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); } while(0);
if (ret != ESP_SDP_SUCCESS) { if (ret != ESP_SDP_SUCCESS) {
@ -1078,7 +1222,18 @@ static void btc_sdp_search(btc_sdp_args_t *arg)
break; break;
} }
if (!sdp_local_param.search_allowed) {
BTC_TRACE_ERROR("%s SDP search is not allowed!", __func__);
ret = ESP_SDP_NO_RESOURCE;
break;
}
BTA_SdpSearch(arg->search.bd_addr, &arg->search.sdp_uuid); BTA_SdpSearch(arg->search.bd_addr, &arg->search.sdp_uuid);
/**
* ESP_SDP_SEARCH_COMP_EVT will refer service name in BTA sdp database, so it is not allowed to be search until
* the previous search is completed
*/
sdp_local_param.search_allowed = false;
} while(0); } while(0);
if (ret != ESP_SDP_SUCCESS) { if (ret != ESP_SDP_SUCCESS) {
@ -1089,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) 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; bluetooth_sdp_record **dst_record = &((btc_sdp_args_t *)p_dest)->create_record.record;
btc_sdp_args_t *src = (btc_sdp_args_t *)p_src; bluetooth_sdp_record *src_record = ((btc_sdp_args_t *)p_src)->create_record.record;
switch (msg->act) { switch (msg->act) {
case BTC_SDP_ACT_CREATE_RECORD: case BTC_SDP_ACT_CREATE_RECORD:
dst->creat_record.record = (bluetooth_sdp_record *)osi_calloc(sizeof(bluetooth_sdp_record)); bluetooth_sdp_record *record = (bluetooth_sdp_record *)osi_calloc(get_sdp_record_size(src_record));
if (dst->creat_record.record) { if (record) {
memcpy(dst->creat_record.record, src->creat_record.record, sizeof(bluetooth_sdp_record)); copy_sdp_record(src_record, record);
} else { } else {
BTC_TRACE_ERROR("%s %d osi_malloc failed\n", __func__, msg->act); BTC_TRACE_ERROR("%s %d osi_malloc failed\n", __func__, msg->act);
break; break;
} }
dst->creat_record.record->hdr.service_name = (char *)osi_calloc(src->creat_record.record->hdr.service_name_length); *dst_record = record;
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; break;
default: default:
break; break;
@ -1117,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) void btc_sdp_arg_deep_free(btc_msg_t *msg)
{ {
btc_sdp_args_t *arg = (btc_sdp_args_t *)msg->arg; btc_sdp_args_t *arg = (btc_sdp_args_t *)msg->arg;
bluetooth_sdp_record *record = arg->create_record.record;
switch (msg->act) { switch (msg->act) {
case BTC_SDP_ACT_CREATE_RECORD: case BTC_SDP_ACT_CREATE_RECORD:
if (arg->creat_record.record) { if (record) {
osi_free(arg->creat_record.record); osi_free(record);
}
if (arg->creat_record.record->hdr.service_name) {
osi_free(arg->creat_record.record->hdr.service_name);
} }
break; break;
default: default:
@ -1172,17 +1320,16 @@ void btc_sdp_cb_handler(btc_msg_t *msg)
param.init.status = p_data->status; param.init.status = p_data->status;
btc_sdp_cb_to_app(ESP_SDP_INIT_EVT, &param); btc_sdp_cb_to_app(ESP_SDP_INIT_EVT, &param);
break; break;
case BTA_SDP_DISENABLE_EVT: case BTA_SDP_DISABLE_EVT:
BTA_SdpDisable(); BTA_SdpCleanup();
osi_mutex_free(&sdp_local_param.sdp_slot_mutex); btc_sdp_cleanup();
#if SDP_DYNAMIC_MEMORY == TRUE
osi_free(sdp_local_param_ptr);
sdp_local_param_ptr = NULL;
#endif
param.deinit.status = ESP_SDP_SUCCESS; param.deinit.status = ESP_SDP_SUCCESS;
btc_sdp_cb_to_app(ESP_SDP_DEINIT_EVT, &param); btc_sdp_cb_to_app(ESP_SDP_DEINIT_EVT, &param);
break; break;
case BTA_SDP_SEARCH_COMP_EVT: case BTA_SDP_SEARCH_COMP_EVT:
// SDP search completed, now can be searched again
sdp_local_param.search_allowed = true;
param.search.status = p_data->sdp_search_comp.status; param.search.status = p_data->sdp_search_comp.status;
if (param.search.status == ESP_SDP_SUCCESS) { 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.remote_addr, p_data->sdp_search_comp.remote_addr, sizeof(BD_ADDR));
@ -1208,7 +1355,17 @@ void btc_sdp_cb_handler(btc_msg_t *msg)
btc_sdp_cb_to_app(ESP_SDP_CREATE_RECORD_COMP_EVT, &param); btc_sdp_cb_to_app(ESP_SDP_CREATE_RECORD_COMP_EVT, &param);
break; break;
case BTA_SDP_REMOVE_RECORD_USER_EVT: 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, &param); btc_sdp_cb_to_app(ESP_SDP_REMOVE_RECORD_COMP_EVT, &param);
break; break;
default: default:
@ -1217,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

View File

@ -48,16 +48,23 @@
//L2CAP //L2CAP
#ifdef CONFIG_BT_L2CAP_ENABLED #ifdef CONFIG_BT_L2CAP_ENABLED
#define UC_BT_L2CAP_ENABLED CONFIG_BT_L2CAP_ENABLED #define UC_BT_L2CAP_ENABLED CONFIG_BT_L2CAP_ENABLED
#else #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 #endif
//HFP(AG) //HFP(AG)
#ifdef CONFIG_BT_HFP_AG_ENABLE #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 #else
#define UC_BT_HFP_AG_ENABLED FALSE #define UC_BT_HFP_AG_ENABLED FALSE
#endif #endif
//HFP(Client) //HFP(Client)

View File

@ -103,10 +103,13 @@
#if (UC_BT_L2CAP_ENABLED == TRUE) #if (UC_BT_L2CAP_ENABLED == TRUE)
#define BTA_JV_INCLUDED TRUE #define BTA_JV_INCLUDED TRUE
#define BTC_L2CAP_INCLUDED TRUE #define BTC_L2CAP_INCLUDED TRUE
#define BTC_SDP_INCLUDED TRUE
#define VND_BT_JV_BTA_L2CAP TRUE #define VND_BT_JV_BTA_L2CAP TRUE
#endif /* UC_BT_L2CAP_ENABLED */ #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) #if (UC_BT_HFP_AG_ENABLED == TRUE) || (UC_BT_HFP_CLIENT_ENABLED == TRUE)
#ifndef RFCOMM_INCLUDED #ifndef RFCOMM_INCLUDED
#define RFCOMM_INCLUDED TRUE #define RFCOMM_INCLUDED TRUE
@ -1500,7 +1503,7 @@
/* The maximum number of attributes in each record. */ /* The maximum number of attributes in each record. */
#ifndef SDP_MAX_REC_ATTR #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 #define SDP_MAX_REC_ATTR 25
#else #else
#define SDP_MAX_REC_ATTR 8 #define SDP_MAX_REC_ATTR 8

View File

@ -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. ** Description This function is called to create a record in the database.
** This would be through the SDP database maintenance API. The ** 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. ** "add_attribute" to add the record's attributes.
** **
** Returns Record handle if OK, else 0. ** Returns Record handle if OK, else 0.
@ -293,15 +293,15 @@ UINT32 SDP_CreateRecord (void)
/* First, check if there is a free record */ /* First, check if there is a free record */
if (p_db->num_records < SDP_MAX_RECORDS) { if (p_db->num_records < SDP_MAX_RECORDS) {
p_rec =(tSDP_RECORD *)osi_malloc(sizeof(tSDP_RECORD)); p_rec = (tSDP_RECORD *)osi_malloc(sizeof(tSDP_RECORD));
if (p_rec) { if (p_rec) {
memset(p_rec, 0, sizeof(tSDP_RECORD)); memset(p_rec, 0, sizeof(tSDP_RECORD));
/* Save previous rec */ /* Save previous rec */
if (p_db->num_records) { if (p_db->num_records) {
p_rec_prev = list_back(p_db->p_record_list); p_rec_prev = list_back(p_db->p_record_list);
} }
/* Append new record */ /* Append new record */
list_append(p_db->p_record_list, p_rec); list_append(p_db->p_record_list, p_rec);
/* We will use a handle of the first unreserved handle plus last record /* We will use a handle of the first unreserved handle plus last record
** number + 1 */ ** number + 1 */
@ -321,10 +321,12 @@ UINT32 SDP_CreateRecord (void)
4, buf); 4, buf);
return (p_rec->record_handle); return (p_rec->record_handle);
} else { }
else {
SDP_TRACE_ERROR("SDP_CreateRecord fail, memory allocation failed\n"); 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); SDP_TRACE_ERROR("SDP_CreateRecord fail, exceed maximum records:%d\n", SDP_MAX_RECORDS);
} }
#endif #endif
@ -354,17 +356,17 @@ BOOLEAN SDP_DeleteRecord (UINT32 handle)
if (handle == 0 || sdp_cb.server_db.num_records == 0) { if (handle == 0 || sdp_cb.server_db.num_records == 0) {
/* Delete all records in the database */ /* Delete all records in the database */
sdp_cb.server_db.num_records = 0; 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)) { 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); list_remove(sdp_cb.server_db.p_record_list, p_node);
} }
/* require new DI record to be created in SDP_SetLocalDiRecord */ /* require new DI record to be created in SDP_SetLocalDiRecord */
sdp_cb.server_db.di_primary_handle = 0; sdp_cb.server_db.di_primary_handle = 0;
return (TRUE); return (TRUE);
} else { } else {
/* Find the record in the database */ /* 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)) { 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); p_rec = list_node(p_node);
if (p_rec->record_handle == handle) { if (p_rec->record_handle == handle) {
/* Found it. Shift everything up one */ /* Found it. Shift everything up one */
list_remove(sdp_cb.server_db.p_record_list, p_rec); 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); 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 */ /* if we're deleting the primary DI record, clear the */
/* value in the control block */ /* 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; sdp_cb.server_db.di_primary_handle = 0;
} }

View File

@ -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

View File

@ -7,3 +7,4 @@ Migration from 5.3 to 5.4
:maxdepth: 1 :maxdepth: 1
system system
bluetooth-classic

View File

@ -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`` 被删除

View File

@ -7,3 +7,4 @@
:maxdepth: 1 :maxdepth: 1
system system
bluetooth-classic

View File

@ -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) 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; esp_sdp_cb_param_t *sdp_param = (esp_sdp_cb_param_t *)p_param;
char bda_str[18] = {0}; 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); ESP_LOGI(SDP_TAG, "ESP_SDP_INIT_EVT: status:%d", sdp_param->init.status);
if (sdp_param->init.status == ESP_SDP_SUCCESS) { if (sdp_param->init.status == ESP_SDP_SUCCESS) {
record.hdr.type = ESP_SDP_TYPE_RAW; 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_length = strlen(sdp_service_name) + 1;
record.hdr.service_name = sdp_service_name; record.hdr.service_name = sdp_service_name;
record.hdr.rfcomm_channel_number = BT_UNUSED_RFCOMM; record.hdr.rfcomm_channel_number = BT_UNUSED_RFCOMM;
record.hdr.l2cap_psm = BT_L2CAP_DYNMIC_PSM; record.hdr.l2cap_psm = BT_L2CAP_DYNMIC_PSM;
record.hdr.profile_version = BT_UNKONWN_PROFILE_VERSION; 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; break;
case ESP_SDP_DEINIT_EVT: case ESP_SDP_DEINIT_EVT:

View File

@ -7,3 +7,4 @@ CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=y CONFIG_BT_BLUEDROID_ENABLED=y
CONFIG_BT_CLASSIC_ENABLED=y CONFIG_BT_CLASSIC_ENABLED=y
CONFIG_BT_L2CAP_ENABLED=y CONFIG_BT_L2CAP_ENABLED=y
CONFIG_BT_SDP_COMMON_ENABLED=y

View File

@ -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) 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; esp_sdp_cb_param_t *sdp_param = (esp_sdp_cb_param_t *)p_param;
switch (event) { 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); ESP_LOGI(SDP_TAG, "ESP_SDP_INIT_EVT: status:%d", sdp_param->init.status);
if (sdp_param->init.status == ESP_SDP_SUCCESS) { if (sdp_param->init.status == ESP_SDP_SUCCESS) {
record.hdr.type = ESP_SDP_TYPE_RAW; 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_length = strlen(sdp_service_name) + 1;
record.hdr.service_name = sdp_service_name; record.hdr.service_name = sdp_service_name;
record.hdr.rfcomm_channel_number = BT_UNUSED_RFCOMM; record.hdr.rfcomm_channel_number = BT_UNUSED_RFCOMM;
record.hdr.l2cap_psm = BT_L2CAP_DYNMIC_PSM; record.hdr.l2cap_psm = BT_L2CAP_DYNMIC_PSM;
record.hdr.profile_version = BT_UNKONWN_PROFILE_VERSION; 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; break;
case ESP_SDP_DEINIT_EVT: case ESP_SDP_DEINIT_EVT:

View File

@ -7,3 +7,4 @@ CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=y CONFIG_BT_BLUEDROID_ENABLED=y
CONFIG_BT_CLASSIC_ENABLED=y CONFIG_BT_CLASSIC_ENABLED=y
CONFIG_BT_L2CAP_ENABLED=y CONFIG_BT_L2CAP_ENABLED=y
CONFIG_BT_SDP_COMMON_ENABLED=y

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Unlicense OR CC0-1.0 * SPDX-License-Identifier: Unlicense OR CC0-1.0
*/ */
@ -32,6 +32,9 @@
#endif #endif
#include "esp_bt_main.h" #include "esp_bt_main.h"
#include "esp_bt_device.h" #include "esp_bt_device.h"
#if CONFIG_BT_SDP_COMMON_ENABLED
#include "esp_sdp_api.h"
#endif /* CONFIG_BT_SDP_COMMON_ENABLED */
#endif #endif
#include "esp_hidd.h" #include "esp_hidd.h"
@ -847,6 +850,47 @@ static void bt_hidd_event_callback(void *handler_args, esp_event_base_t base, in
} }
return; return;
} }
#if CONFIG_BT_SDP_COMMON_ENABLED
static void esp_sdp_cb(esp_sdp_cb_event_t event, esp_sdp_cb_param_t *param)
{
switch (event) {
case ESP_SDP_INIT_EVT:
ESP_LOGI(TAG, "ESP_SDP_INIT_EVT: status:%d", param->init.status);
if (param->init.status == ESP_SDP_SUCCESS) {
esp_bluetooth_sdp_dip_record_t dip_record = {
.hdr =
{
.type = ESP_SDP_TYPE_DIP_SERVER,
},
.vendor = bt_hid_config.vendor_id,
.vendor_id_source = ESP_SDP_VENDOR_ID_SRC_BT,
.product = bt_hid_config.product_id,
.version = bt_hid_config.version,
.primary_record = true,
};
esp_sdp_create_record((esp_bluetooth_sdp_record_t *)&dip_record);
}
break;
case ESP_SDP_DEINIT_EVT:
ESP_LOGI(TAG, "ESP_SDP_DEINIT_EVT: status:%d", param->deinit.status);
break;
case ESP_SDP_SEARCH_COMP_EVT:
ESP_LOGI(TAG, "ESP_SDP_SEARCH_COMP_EVT: status:%d", param->search.status);
break;
case ESP_SDP_CREATE_RECORD_COMP_EVT:
ESP_LOGI(TAG, "ESP_SDP_CREATE_RECORD_COMP_EVT: status:%d, handle:0x%x", param->create_record.status,
param->create_record.record_handle);
break;
case ESP_SDP_REMOVE_RECORD_COMP_EVT:
ESP_LOGI(TAG, "ESP_SDP_REMOVE_RECORD_COMP_EVT: status:%d", param->remove_record.status);
break;
default:
break;
}
}
#endif /* CONFIG_BT_SDP_COMMON_ENABLED */
#endif #endif
#if CONFIG_BT_NIMBLE_ENABLED #if CONFIG_BT_NIMBLE_ENABLED
@ -911,7 +955,11 @@ void app_main(void)
ESP_LOGI(TAG, "setting bt device"); ESP_LOGI(TAG, "setting bt device");
ESP_ERROR_CHECK( ESP_ERROR_CHECK(
esp_hidd_dev_init(&bt_hid_config, ESP_HID_TRANSPORT_BT, bt_hidd_event_callback, &s_bt_hid_param.hid_dev)); esp_hidd_dev_init(&bt_hid_config, ESP_HID_TRANSPORT_BT, bt_hidd_event_callback, &s_bt_hid_param.hid_dev));
#endif #if CONFIG_BT_SDP_COMMON_ENABLED
ESP_ERROR_CHECK(esp_sdp_register_callback(esp_sdp_cb));
ESP_ERROR_CHECK(esp_sdp_init());
#endif /* CONFIG_BT_SDP_COMMON_ENABLED */
#endif /* CONFIG_BT_HID_DEVICE_ENABLED */
#if CONFIG_BT_NIMBLE_ENABLED #if CONFIG_BT_NIMBLE_ENABLED
/* XXX Need to have template for store */ /* XXX Need to have template for store */
ble_store_config_init(); ble_store_config_init();

View File

@ -5,5 +5,6 @@ CONFIG_BT_CLASSIC_ENABLED=y
CONFIG_BT_BLE_ENABLED=y CONFIG_BT_BLE_ENABLED=y
CONFIG_BT_HID_ENABLED=y CONFIG_BT_HID_ENABLED=y
CONFIG_BT_HID_DEVICE_ENABLED=y CONFIG_BT_HID_DEVICE_ENABLED=y
CONFIG_BT_SDP_COMMON_ENABLED=y
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y