Merge branch 'feat/add_param_indicate_create_spp_records' into 'master'

feat(bt): Add an SPP API parameter to indicate whether to create the SPP record

See merge request espressif/esp-idf!43485
This commit is contained in:
Wang Meng Yang
2025-11-21 15:47:10 +08:00
4 changed files with 63 additions and 14 deletions

View File

@@ -133,22 +133,34 @@ esp_err_t esp_spp_disconnect(uint32_t handle)
esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask,
esp_spp_role_t role, uint8_t local_scn, const char *name)
{
esp_spp_start_srv_cfg_t cfg = {0};
cfg.local_scn = local_scn;
cfg.sec_mask = sec_mask;
cfg.role = role;
cfg.create_spp_record = true;
cfg.name = name;
return esp_spp_start_srv_with_cfg(&cfg);
}
esp_err_t esp_spp_start_srv_with_cfg(const esp_spp_start_srv_cfg_t *cfg)
{
btc_msg_t msg;
btc_spp_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (name == NULL || strlen(name) > ESP_SPP_SERVER_NAME_MAX) {
if (cfg == NULL || cfg->name == NULL || strlen(cfg->name) > ESP_SPP_SERVER_NAME_MAX) {
LOG_ERROR("Invalid server name!\n");
return ESP_ERR_INVALID_ARG;
}
if (sec_mask != ESP_SPP_SEC_NONE &&
sec_mask != ESP_SPP_SEC_AUTHENTICATE &&
sec_mask != (ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT) &&
sec_mask != ESP_SPP_SEC_IN_16_DIGITS &&
sec_mask != (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE) &&
sec_mask != (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT)) {
if (cfg->sec_mask != ESP_SPP_SEC_NONE &&
cfg->sec_mask != ESP_SPP_SEC_AUTHENTICATE &&
cfg->sec_mask != (ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT) &&
cfg->sec_mask != ESP_SPP_SEC_IN_16_DIGITS &&
cfg->sec_mask != (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE) &&
cfg->sec_mask != (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT)) {
LOG_WARN("Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHENTICATE,"
"(ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT),"
"ESP_SPP_SEC_IN_16_DIGITS, (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE), or"
@@ -159,11 +171,12 @@ esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask,
msg.pid = BTC_PID_SPP;
msg.act = BTC_SPP_ACT_START_SRV;
arg.start_srv.sec_mask = sec_mask;
arg.start_srv.role = role;
arg.start_srv.local_scn = local_scn;
arg.start_srv.sec_mask = cfg->sec_mask;
arg.start_srv.role = cfg->role;
arg.start_srv.local_scn = cfg->local_scn;
arg.start_srv.create_spp_record = cfg->create_spp_record;
arg.start_srv.max_session = ESP_SPP_MAX_SESSION;
strcpy(arg.start_srv.name, name);
strcpy(arg.start_srv.name, cfg->name);
return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

View File

@@ -74,7 +74,7 @@ typedef enum {
} esp_spp_mode_t;
/**
* @brief SPP configuration parameters
* @brief SPP initialization configuration parameters.
*/
typedef struct {
esp_spp_mode_t mode; /*!< Choose the mode of SPP, ESP_SPP_MODE_CB or ESP_SPP_MODE_VFS. */
@@ -82,6 +82,17 @@ typedef struct {
uint16_t tx_buffer_size; /*!< Tx buffer size for a new SPP channel. A smaller setting can save memory, but may incur a decrease in throughput. Only for ESP_SPP_MODE_VFS mode. */
} esp_spp_cfg_t;
/**
* @brief SPP start server configuration parameters.
*/
typedef struct {
uint8_t local_scn; /*!< The specific channel you want to get. If channel is 0, means get any channel. */
bool create_spp_record; /*!< Specifies whether to create the SPP record */
esp_spp_sec_t sec_mask; /*!< Security Setting Mask. Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only */
esp_spp_role_t role; /*!< Master or slave. */
const char *name; /*!< Server's name. */
} esp_spp_start_srv_cfg_t;
/**
* @brief SPP callback function events
*/
@@ -354,6 +365,19 @@ esp_err_t esp_spp_disconnect(uint32_t handle);
*/
esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask, esp_spp_role_t role, uint8_t local_scn, const char *name);
/**
* @brief This function is similar to `esp_spp_start_srv`.
* The only difference is that it adds a parameter to specify whether to create the SPP record.
* @note If the SPP record is not created, it is suggested to use it together with the SDP API.
*
* @param[in] cfg: Configuration parameters for starting the server.
*
* @return
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_spp_start_srv_with_cfg(const esp_spp_start_srv_cfg_t *cfg);
/**
* @brief This function stops all SPP servers.
* The operation will close all active SPP connection first, then the callback function will be called

View File

@@ -67,6 +67,7 @@ typedef union {
esp_spp_sec_t sec_mask;
esp_spp_role_t role;
UINT8 local_scn;
bool create_spp_record;
UINT8 max_session;
char name[ESP_SPP_SERVER_NAME_MAX + 1];
} start_srv;

View File

@@ -50,6 +50,7 @@ typedef struct {
bool connected;
bool is_server;
bool is_writing;
bool create_spp_record;
uint8_t serial;
uint8_t scn;
uint8_t max_session;
@@ -143,6 +144,7 @@ static spp_slot_t *spp_malloc_slot(void)
(*slot)->rfc_port_handle = 0;
(*slot)->fd = -1;
(*slot)->connected = false;
(*slot)->create_spp_record = false;
(*slot)->is_server = false;
(*slot)->mtu = 0;
(*slot)->credit_rx = BTA_JV_MAX_CREDIT_NUM;
@@ -378,6 +380,7 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u
strcpy(slot_new->service_name, slot->service_name);
slot_new->sdp_handle = slot->sdp_handle;
slot_new->mtu = p_data->rfc_srv_open.peer_mtu;
slot_new->create_spp_record = slot->create_spp_record;
slot_new->rfc_handle = p_data->rfc_srv_open.handle;
slot_new->rfc_port_handle = BTA_JvRfcommGetPortHdl(slot_new->rfc_handle);
BTA_JvSetPmProfile(p_data->rfc_srv_open.handle, BTA_JV_PM_ALL, BTA_JV_CONN_OPEN);
@@ -482,7 +485,14 @@ static void btc_spp_dm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_d
}
slot->scn = p_data->scn;
BTA_JvCreateRecordByUser(slot->service_name, slot->scn, (void *)slot->id);
if (slot->create_spp_record) {
BTA_JvCreateRecordByUser(slot->service_name, slot->scn, (void *)slot->id);
} else {
slot->sdp_handle = 0xffff;
BTA_JvRfcommStartServer(slot->security, slot->role, slot->scn,
slot->max_session, (tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)slot->id);
}
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
break;
case BTA_JV_CREATE_RECORD_EVT:
@@ -748,6 +758,7 @@ static void btc_spp_start_srv(btc_spp_args_t *arg)
* make this slot become a listening slot
*/
slot->is_server = true;
slot->create_spp_record = arg->start_srv.create_spp_record;
slot->security = arg->start_srv.sec_mask;
slot->role = arg->start_srv.role;
slot->scn = arg->start_srv.local_scn;
@@ -832,7 +843,7 @@ static void btc_spp_stop_srv(btc_spp_args_t *arg)
if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->is_server &&
spp_local_param.spp_slots[i]->sdp_handle > 0 &&
spp_local_param.spp_slots[i]->scn == srv_scn_arr[j]) {
if (spp_local_param.spp_slots[i]->sdp_handle > 0) {
if (spp_local_param.spp_slots[i]->sdp_handle > 0 && spp_local_param.spp_slots[i]->create_spp_record) {
BTA_JvDeleteRecord(spp_local_param.spp_slots[i]->sdp_handle);
}