From 67efd21f3ddfe033a4007d1c288260044b98c1de Mon Sep 17 00:00:00 2001 From: xiongweichao Date: Tue, 18 Nov 2025 17:11:52 +0800 Subject: [PATCH] feat(bt): Adds an SPP API parameter to indicate whether to create SPP record --- .../bt/host/bluedroid/api/esp_spp_api.c | 35 +++++++++++++------ .../bluedroid/api/include/api/esp_spp_api.h | 26 +++++++++++++- .../btc/profile/std/include/btc_spp.h | 1 + .../bluedroid/btc/profile/std/spp/btc_spp.c | 15 ++++++-- 4 files changed, 63 insertions(+), 14 deletions(-) diff --git a/components/bt/host/bluedroid/api/esp_spp_api.c b/components/bt/host/bluedroid/api/esp_spp_api.c index 31a18ab235..ac05fe3557 100644 --- a/components/bt/host/bluedroid/api/esp_spp_api.c +++ b/components/bt/host/bluedroid/api/esp_spp_api.c @@ -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); } diff --git a/components/bt/host/bluedroid/api/include/api/esp_spp_api.h b/components/bt/host/bluedroid/api/include/api/esp_spp_api.h index f47e0c1185..745047cb4d 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_spp_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_spp_api.h @@ -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 diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_spp.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_spp.h index 5082a135e1..fd349c7de6 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_spp.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_spp.h @@ -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; diff --git a/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c b/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c index bb142531a3..8607e42191 100644 --- a/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c +++ b/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c @@ -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); }