Ver código fonte

bt: Added esp_spp_enhance_init() API to indicate whether to enable L2CAP ERTM

xiongweichao 3 anos atrás
pai
commit
ecf2eea1d6

+ 13 - 1
components/bt/host/bluedroid/api/esp_spp_api.c

@@ -34,6 +34,16 @@ esp_err_t esp_spp_register_callback(esp_spp_cb_t callback)
 
 
 esp_err_t esp_spp_init(esp_spp_mode_t mode)
+{
+    esp_spp_cfg_t bt_spp_cfg = {
+        .mode = mode,
+        .enable_l2cap_ertm = true,
+    };
+
+    return esp_spp_enhanced_init(&bt_spp_cfg);
+}
+
+esp_err_t esp_spp_enhanced_init(const esp_spp_cfg_t *cfg)
 {
     btc_msg_t msg;
     btc_spp_args_t arg;
@@ -43,7 +53,9 @@ esp_err_t esp_spp_init(esp_spp_mode_t mode)
     msg.pid = BTC_PID_SPP;
     msg.act = BTC_SPP_ACT_INIT;
 
-    arg.init.mode = mode;
+    arg.init.mode = cfg->mode;
+    arg.init.enable_l2cap_ertm = cfg->enable_l2cap_ertm;
+
     return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
 }
 

+ 55 - 21
components/bt/host/bluedroid/api/include/api/esp_spp_api.h

@@ -14,17 +14,16 @@
 extern "C" {
 #endif
 
-typedef enum {
-    ESP_SPP_SUCCESS   = 0,          /*!< Successful operation. */
-    ESP_SPP_FAILURE,                /*!< Generic failure. */
-    ESP_SPP_BUSY,                   /*!< Temporarily can not handle this request. */
-    ESP_SPP_NO_DATA,                /*!< No data */
-    ESP_SPP_NO_RESOURCE,            /*!< No more resource */
-    ESP_SPP_NEED_INIT,              /*!< SPP module shall init first */
-    ESP_SPP_NEED_DEINIT,            /*!< SPP module shall deinit first */
-    ESP_SPP_NO_CONNECTION,          /*!< Connection may have been closed */
-    ESP_SPP_NO_SERVER,              /*!< No SPP server */
-} esp_spp_status_t;
+#define ESP_SPP_MAX_MTU                 (3*330)     /*!< SPP max MTU */
+#define ESP_SPP_MAX_SCN                 31          /*!< SPP max SCN */
+
+/**
+ * @brief SPP default configuration
+ */
+#define BT_SPP_DEFAULT_CONFIG() { \
+    .mode = ESP_SPP_MODE_VFS, \
+    .enable_l2cap_ertm = true, \
+}
 
 /* Security Setting Mask
 Use these three mask mode:
@@ -41,6 +40,18 @@ Use these three mask mode:
 #define ESP_SPP_SEC_IN_16_DIGITS    0x4000    /*!< Min 16 digit for pin code  relate to BTA_SEC_IN_16_DIGITS in bta/bta_api.h*/
 typedef uint16_t esp_spp_sec_t;
 
+typedef enum {
+    ESP_SPP_SUCCESS   = 0,          /*!< Successful operation. */
+    ESP_SPP_FAILURE,                /*!< Generic failure. */
+    ESP_SPP_BUSY,                   /*!< Temporarily can not handle this request. */
+    ESP_SPP_NO_DATA,                /*!< No data */
+    ESP_SPP_NO_RESOURCE,            /*!< No more resource */
+    ESP_SPP_NEED_INIT,              /*!< SPP module shall init first */
+    ESP_SPP_NEED_DEINIT,            /*!< SPP module shall deinit first */
+    ESP_SPP_NO_CONNECTION,          /*!< Connection may have been closed */
+    ESP_SPP_NO_SERVER,              /*!< No SPP server */
+} esp_spp_status_t;
+
 typedef enum {
     ESP_SPP_ROLE_MASTER     = 0,          /*!< Role: master */
     ESP_SPP_ROLE_SLAVE      = 1,          /*!< Role: slave */
@@ -51,8 +62,14 @@ typedef enum {
     ESP_SPP_MODE_VFS        = 1,          /*!< Use VFS to write/read data */
 } esp_spp_mode_t;
 
-#define ESP_SPP_MAX_MTU                 (3*330)     /*!< SPP max MTU */
-#define ESP_SPP_MAX_SCN                 31          /*!< SPP max SCN */
+/**
+ * @brief SPP configuration parameters
+ */
+typedef struct {
+    esp_spp_mode_t mode;                  /*!< Choose the mode of SPP, ESP_SPP_MODE_CB or ESP_SPP_MODE_VFS. */
+    bool enable_l2cap_ertm;               /*!< Enable/disable Logical Link Control and Adaptation Layer Protocol enhanced retransmission mode. */
+} esp_spp_cfg_t;
+
 /**
  * @brief SPP callback function events
  */
@@ -221,14 +238,31 @@ esp_err_t esp_spp_register_callback(esp_spp_cb_t callback);
  *              - ESP_OK: success
  *              - other: failed
  */
-esp_err_t esp_spp_init(esp_spp_mode_t mode);
+esp_err_t esp_spp_init(esp_spp_mode_t mode) __attribute__((deprecated("Please use esp_spp_enhanced_init")));
+
+
+/**
+ * @brief       This function is called to init SPP module.
+ *              When the operation is completed, the callback function will be called with ESP_SPP_INIT_EVT.
+ *              This function should be called after esp_bluedroid_enable() completes successfully.
+ *
+ * @param[in]   cfg: SPP configuration.
+ *
+ * @note        The member variable enable_l2cap_etrm in esp_spp_cfg_t can affect all L2CAP channel
+ *              configurations of the upper layer RFCOMM protocol.
+ *
+ * @return
+ *              - ESP_OK: success
+ *              - other: failed
+ */
+esp_err_t esp_spp_enhanced_init(const esp_spp_cfg_t *cfg);
 
 /**
  * @brief       This function is called to uninit SPP module.
  *              The operation will close all active SPP connection first, then the callback function will be called
  *              with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection.
  *              When the operation is completed, the callback function will be called with ESP_SPP_UNINIT_EVT.
- *              This function should be called after esp_spp_init() completes successfully.
+ *              This function should be called after esp_spp_init()/esp_spp_enhanced_init() completes successfully.
  *
  * @return
  *              - ESP_OK: success
@@ -240,7 +274,7 @@ esp_err_t esp_spp_deinit(void);
 /**
  * @brief       This function is called to performs service discovery for the services provided by the given peer device.
  *              When the operation is completed, the callback function will be called with ESP_SPP_DISCOVERY_COMP_EVT.
- *              This function must be called after esp_spp_init() successful and before esp_spp_deinit().
+ *              This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit().
  *
  * @param[in]   bd_addr:   Remote device bluetooth device address.
  *
@@ -254,7 +288,7 @@ esp_err_t esp_spp_start_discovery(esp_bd_addr_t bd_addr);
  * @brief       This function makes an SPP connection to a remote BD Address.
  *              When the connection is initiated or failed to initiate, the callback is called with ESP_SPP_CL_INIT_EVT.
  *              When the connection is established or failed, the callback is called with ESP_SPP_OPEN_EVT.
- *              This function must be called after esp_spp_init() successful and before esp_spp_deinit().
+ *              This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit().
  *
  * @param[in]   sec_mask:     Security Setting Mask. Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only.
  * @param[in]   role:         Master or slave.
@@ -270,7 +304,7 @@ esp_err_t esp_spp_connect(esp_spp_sec_t sec_mask, esp_spp_role_t role, uint8_t r
 /**
  * @brief       This function closes an SPP connection.
  *              When the operation is completed, the callback function will be called with ESP_SPP_CLOSE_EVT.
- *              This function must be called after esp_spp_init() successful and before esp_spp_deinit().
+ *              This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit().
  *
  * @param[in]   handle:    The connection handle.
  *
@@ -285,7 +319,7 @@ esp_err_t esp_spp_disconnect(uint32_t handle);
  *              SPP connection request from a remote Bluetooth device.
  *              When the server is started successfully, the callback is called with ESP_SPP_START_EVT.
  *              When the connection is established, the callback is called with ESP_SPP_SRV_OPEN_EVT.
- *              This function must be called after esp_spp_init() successful and before esp_spp_deinit().
+ *              This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit().
  *
  * @param[in]   sec_mask:     Security Setting Mask. Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only.
  * @param[in]   role:         Master or slave.
@@ -304,7 +338,7 @@ esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask, esp_spp_role_t role, uint8_t
  *              The operation will close all active SPP connection first, then the callback function will be called
  *              with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection.
  *              When the operation is completed, the callback is called with ESP_SPP_SRV_STOP_EVT.
- *              This function must be called after esp_spp_init() successful and before esp_spp_deinit().
+ *              This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit().
  *
  * @return
  *              - ESP_OK: success
@@ -318,7 +352,7 @@ esp_err_t esp_spp_stop_srv(void);
  *              The operation will close all active SPP connection first on the specific SPP server, then the callback function will be called
  *              with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection.
  *              When the operation is completed, the callback is called with ESP_SPP_SRV_STOP_EVT.
- *              This function must be called after esp_spp_init() successful and before esp_spp_deinit().
+ *              This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit().
  *
  * @param[in]   scn:         Server channel number.
  *

+ 13 - 0
components/bt/host/bluedroid/bta/include/bta/bta_jv_api.h

@@ -805,6 +805,19 @@ extern tBTA_JV_STATUS BTA_JvL2capWriteFixed(UINT16 channel, BD_ADDR *addr, UINT3
 #endif /* BTA_JV_L2CAP_INCLUDED */
 
 #if BTA_JV_RFCOMM_INCLUDED
+/*******************************************************************************
+**
+** Function         BTA_JvRfcommConfig
+**
+** Description      This function is to configure RFCOMM.
+**
+**
+** Returns          BTA_JV_SUCCESS, if the request is being processed.
+**                  BTA_JV_FAILURE, otherwise.
+**
+*******************************************************************************/
+extern tBTA_JV_STATUS BTA_JvRfcommConfig(BOOLEAN enable_l2cap_ertm);
+
 /*******************************************************************************
 **
 ** Function         BTA_JvRfcommConnect

+ 16 - 0
components/bt/host/bluedroid/bta/jv/bta_jv_act.c

@@ -1764,6 +1764,22 @@ static void bta_jv_port_event_cl_cback(UINT32 code, UINT16 port_handle)
     }
 }
 
+/*******************************************************************************
+**
+** Function     bta_jv_rfcomm_config
+**
+** Description  Configure RFCOMM
+**
+** Returns      void
+**
+*******************************************************************************/
+void bta_jv_rfcomm_config(tBTA_JV_MSG *p_data)
+{
+    APPL_TRACE_DEBUG("%s enable_l2cap_ertm:%d", __func__, p_data->rfcomm_config.enable_l2cap_ertm);
+
+    PORT_SetL2capErtm(p_data->rfcomm_config.enable_l2cap_ertm);
+}
+
 /*******************************************************************************
 **
 ** Function     bta_jv_rfcomm_connect

+ 27 - 0
components/bt/host/bluedroid/bta/jv/bta_jv_api.c

@@ -862,6 +862,33 @@ tBTA_JV_STATUS BTA_JvL2capWriteFixed(UINT16 channel, BD_ADDR *addr, UINT32 req_i
 #endif /* BTA_JV_L2CAP_INCLUDED */
 
 #if BTA_JV_RFCOMM_INCLUDED
+/*******************************************************************************
+**
+** Function         BTA_JvRfcommConfig
+**
+** Description      This function is to configure RFCOMM.
+**
+** Returns          BTA_JV_SUCCESS, if the request is being processed.
+**                  BTA_JV_FAILURE, otherwise.
+**
+*******************************************************************************/
+tBTA_JV_STATUS BTA_JvRfcommConfig(BOOLEAN enable_l2cap_ertm)
+{
+    tBTA_JV_STATUS status = BTA_JV_FAILURE;
+    tBTA_JV_API_RFCOMM_CONFIG *p_msg;
+
+    APPL_TRACE_API( "%s", __func__);
+
+    if ((p_msg = (tBTA_JV_API_RFCOMM_CONFIG *)osi_malloc(sizeof(tBTA_JV_API_RFCOMM_CONFIG))) != NULL) {
+        p_msg->hdr.event = BTA_JV_API_RFCOMM_CONFIG_EVT;
+        p_msg->enable_l2cap_ertm = enable_l2cap_ertm;
+        bta_sys_sendmsg(p_msg);
+        status = BTA_JV_SUCCESS;
+    }
+
+    return (status);
+}
+
 /*******************************************************************************
 **
 ** Function         BTA_JvRfcommConnect

+ 2 - 1
components/bt/host/bluedroid/bta/jv/bta_jv_main.c

@@ -63,6 +63,7 @@ const tBTA_JV_ACTION bta_jv_action[] = {
     bta_jv_l2cap_write,             /* BTA_JV_API_L2CAP_WRITE_EVT */
 #endif /* BTA_JV_L2CAP_INCLUDED */
 #if BTA_JV_RFCOMM_INCLUDED
+    bta_jv_rfcomm_config,           /* BTA_JV_API_RFCOMM_CONFIG_EVT */
     bta_jv_rfcomm_connect,          /* BTA_JV_API_RFCOMM_CONNECT_EVT */
     bta_jv_rfcomm_close,            /* BTA_JV_API_RFCOMM_CLOSE_EVT */
     bta_jv_rfcomm_start_server,     /* BTA_JV_API_RFCOMM_START_SERVER_EVT */
@@ -70,7 +71,7 @@ const tBTA_JV_ACTION bta_jv_action[] = {
     bta_jv_rfcomm_read,             /* BTA_JV_API_RFCOMM_READ_EVT */
     bta_jv_rfcomm_write,            /* BTA_JV_API_RFCOMM_WRITE_EVT */
     bta_jv_rfcomm_flow_control,     /* BTA_JV_API_RFCOMM_FLOW_CONTROL_EVT */
-    #endif /* BTA_JV_RFCOMM_INCLUDED */
+#endif /* BTA_JV_RFCOMM_INCLUDED */
     bta_jv_set_pm_profile,          /* BTA_JV_API_SET_PM_PROFILE_EVT */
     bta_jv_change_pm_state,         /* BTA_JV_API_PM_STATE_CHANGE_EVT */
 #if BTA_JV_L2CAP_INCLUDED

+ 10 - 1
components/bt/host/bluedroid/bta/jv/include/bta_jv_int.h

@@ -57,6 +57,7 @@ enum {
     BTA_JV_API_L2CAP_WRITE_EVT,
 #endif /* BTA_JV_L2CAP_INCLUDED */
 #if BTA_JV_RFCOMM_INCLUDED
+    BTA_JV_API_RFCOMM_CONFIG_EVT,
     BTA_JV_API_RFCOMM_CONNECT_EVT,
     BTA_JV_API_RFCOMM_CLOSE_EVT,
     BTA_JV_API_RFCOMM_START_SERVER_EVT,
@@ -83,7 +84,7 @@ enum {
 
 /* data type for BTA_JV_API_ENABLE_EVT */
 typedef struct {
-    BT_HDR          hdr;
+    BT_HDR              hdr;
     tBTA_JV_DM_CBACK   *p_cback;
 } tBTA_JV_API_ENABLE;
 
@@ -257,6 +258,12 @@ typedef struct {
 #endif /* BTA_JV_L2CAP_INCLUDED */
 
 #if BTA_JV_RFCOMM_INCLUDED
+/* data type for BTA_JV_API_RFCOMM_CONFIG_EVT */
+typedef struct {
+    BT_HDR          hdr;
+    BOOLEAN         enable_l2cap_ertm;
+} tBTA_JV_API_RFCOMM_CONFIG;
+
 /* data type for BTA_JV_API_RFCOMM_CONNECT_EVT */
 typedef struct {
     BT_HDR          hdr;
@@ -392,6 +399,7 @@ typedef union {
     tBTA_JV_API_L2CAP_WRITE_FIXED   l2cap_write_fixed;
 #endif /* BTA_JV_L2CAP_INCLUDED */
 #if BTA_JV_RFCOMM_INCLUDED
+    tBTA_JV_API_RFCOMM_CONFIG       rfcomm_config;
     tBTA_JV_API_RFCOMM_CONNECT      rfcomm_connect;
     tBTA_JV_API_RFCOMM_READ         rfcomm_read;
     tBTA_JV_API_RFCOMM_WRITE        rfcomm_write;
@@ -463,6 +471,7 @@ extern void bta_jv_l2cap_read (tBTA_JV_MSG *p_data);
 extern void bta_jv_l2cap_write (tBTA_JV_MSG *p_data);
 #endif /* BTA_JV_L2CAP_INCLUDED */
 #if BTA_JV_RFCOMM_INCLUDED
+extern void bta_jv_rfcomm_config (tBTA_JV_MSG *p_data);
 extern void bta_jv_rfcomm_connect (tBTA_JV_MSG *p_data);
 extern void bta_jv_rfcomm_close (tBTA_JV_MSG *p_data);
 extern void bta_jv_rfcomm_start_server (tBTA_JV_MSG *p_data);

+ 1 - 0
components/bt/host/bluedroid/btc/profile/std/include/btc_spp.h

@@ -36,6 +36,7 @@ typedef union {
     //BTC_SPP_ACT_INIT
     struct init_arg {
         esp_spp_mode_t mode;
+        bool enable_l2cap_ertm;
     } init;
     //BTC_SPP_ACT_UNINIT
     struct uninit_arg {

+ 1 - 0
components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c

@@ -548,6 +548,7 @@ static void btc_spp_init(btc_spp_args_t *arg)
         spp_local_param.spp_mode = arg->init.mode;
         spp_local_param.spp_slot_id = 0;
         BTA_JvEnable((tBTA_JV_DM_CBACK *)btc_spp_dm_inter_cb);
+        BTA_JvRfcommConfig(arg->init.enable_l2cap_ertm);
     } while (0);
 
     if (ret != ESP_SPP_SUCCESS) {

+ 11 - 0
components/bt/host/bluedroid/stack/include/stack/port_api.h

@@ -692,6 +692,17 @@ extern UINT8 PORT_SetTraceLevel (UINT8 new_level);
 *******************************************************************************/
 extern const char *PORT_GetResultString (const uint8_t result_code);
 
+/*******************************************************************************
+**
+** Function         PORT_SetL2capErtm
+**
+** Description      This function sets whether RFCOMM uses L2CAP ERTM.
+**
+** Returns          void
+**
+*******************************************************************************/
+extern void PORT_SetL2capErtm (BOOLEAN enable_l2cap_ertm);
+
 #ifdef __cplusplus
 }
 #endif

+ 1 - 0
components/bt/host/bluedroid/stack/rfcomm/include/port_int.h

@@ -209,6 +209,7 @@ typedef struct t_port_info tPORT;
 typedef struct {
     tPORT        port[MAX_RFC_PORTS];            /* Port info pool */
     tRFC_MCB     rfc_mcb[MAX_BD_CONNECTIONS];    /* RFCOMM bd_connections pool */
+    BOOLEAN      enable_l2cap_ertm;              /* enable/disable l2cap ertm */
 } tPORT_CB;
 
 #ifdef __cplusplus

+ 14 - 0
components/bt/host/bluedroid/stack/rfcomm/port_api.c

@@ -1866,4 +1866,18 @@ const char *PORT_GetResultString (const uint8_t result_code)
     return result_code_strings[result_code];
 }
 
+/*******************************************************************************
+**
+** Function         PORT_SetL2capErtm
+**
+** Description      This function sets whether RFCOMM uses L2CAP ERTM.
+**
+** Returns          void
+**
+*******************************************************************************/
+void PORT_SetL2capErtm (BOOLEAN enable_l2cap_ertm)
+{
+    rfc_cb.port.enable_l2cap_ertm = enable_l2cap_ertm;
+}
+
 #endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)

+ 4 - 5
components/bt/host/bluedroid/stack/rfcomm/rfc_l2cap_if.c

@@ -128,8 +128,8 @@ void RFCOMM_ConnectInd (BD_ADDR bd_addr, UINT16 lcid, UINT16 psm, UINT8 id)
     }
 
     if (p_mcb == NULL) {
-        // L2CA_ConnectRsp (bd_addr, id, lcid, L2CAP_CONN_NO_RESOURCES, 0);
-        L2CA_ErtmConnectRsp (bd_addr, id, lcid, L2CAP_CONN_NO_RESOURCES, 0, &rfc_l2c_etm_opt);
+        tL2CAP_ERTM_INFO *ertm_opt = rfc_cb.port.enable_l2cap_ertm ? &rfc_l2c_etm_opt : NULL;
+        L2CA_ErtmConnectRsp (bd_addr, id, lcid, L2CAP_CONN_NO_RESOURCES, 0, ertm_opt);
         return;
     }
     p_mcb->lcid     = lcid;
@@ -189,10 +189,9 @@ void RFCOMM_ConnectCnf (UINT16 lcid, UINT16 result)
         } else {
             RFCOMM_TRACE_DEBUG ("RFCOMM_ConnectCnf peer gave up pending LCID(0x%x)", p_mcb->pending_lcid);
 
+            tL2CAP_ERTM_INFO *ertm_opt = rfc_cb.port.enable_l2cap_ertm ? &rfc_l2c_etm_opt : NULL;
             /* Peer gave up his connection request, make sure cleaning up L2CAP channel */
-            // L2CA_ConnectRsp (p_mcb->bd_addr, p_mcb->pending_id, p_mcb->pending_lcid, L2CAP_CONN_NO_RESOURCES, 0);
-            L2CA_ErtmConnectRsp (p_mcb->bd_addr, p_mcb->pending_id, p_mcb->pending_lcid, L2CAP_CONN_NO_RESOURCES, 0,
-                                    &rfc_l2c_etm_opt);
+            L2CA_ErtmConnectRsp (p_mcb->bd_addr, p_mcb->pending_id, p_mcb->pending_lcid, L2CAP_CONN_NO_RESOURCES, 0, ertm_opt);
 
             p_mcb->pending_lcid = 0;
         }

+ 17 - 8
components/bt/host/bluedroid/stack/rfcomm/rfc_mx_fsm.c

@@ -136,15 +136,20 @@ void rfc_mx_sm_execute (tRFC_MCB *p_mcb, UINT16 event, void *p_data)
 *******************************************************************************/
 void rfc_mx_sm_state_idle (tRFC_MCB *p_mcb, UINT16 event, void *p_data)
 {
+    tL2CAP_ERTM_INFO *ertm_opt = NULL;
+
     RFCOMM_TRACE_EVENT ("rfc_mx_sm_state_idle - evt:%d", event);
+
     switch (event) {
     case RFC_MX_EVENT_START_REQ:
 
         /* Initialize L2CAP MTU */
         p_mcb->peer_l2cap_mtu = L2CAP_DEFAULT_MTU - RFCOMM_MIN_OFFSET - 1;
 
-        // if ((p_mcb->lcid = L2CA_ConnectReq (BT_PSM_RFCOMM, p_mcb->bd_addr)) == 0) {
-        if ((p_mcb->lcid = L2CA_ErtmConnectReq (BT_PSM_RFCOMM, p_mcb->bd_addr, &rfc_l2c_etm_opt)) == 0) {
+        ertm_opt = rfc_cb.port.enable_l2cap_ertm ? &rfc_l2c_etm_opt : NULL;
+        p_mcb->lcid = L2CA_ErtmConnectReq (BT_PSM_RFCOMM, p_mcb->bd_addr, ertm_opt);
+
+        if (p_mcb->lcid == 0) {
             PORT_StartCnf (p_mcb, RFCOMM_ERROR);
             return;
         }
@@ -164,8 +169,8 @@ void rfc_mx_sm_state_idle (tRFC_MCB *p_mcb, UINT16 event, void *p_data)
     case RFC_MX_EVENT_CONN_IND:
 
         rfc_timer_start (p_mcb, RFCOMM_CONN_TIMEOUT);
-        // L2CA_ConnectRsp (p_mcb->bd_addr, *((UINT8 *)p_data), p_mcb->lcid, L2CAP_CONN_OK, 0);
-        L2CA_ErtmConnectRsp (p_mcb->bd_addr, *((UINT8 *)p_data), p_mcb->lcid, L2CAP_CONN_OK, 0, &rfc_l2c_etm_opt);
+        ertm_opt = rfc_cb.port.enable_l2cap_ertm ? &rfc_l2c_etm_opt : NULL;
+        L2CA_ErtmConnectRsp (p_mcb->bd_addr, *((UINT8 *)p_data), p_mcb->lcid, L2CAP_CONN_OK, 0, ertm_opt);
 
         rfc_mx_send_config_req (p_mcb);
 
@@ -502,9 +507,11 @@ void rfc_mx_sm_state_disc_wait_ua (tRFC_MCB *p_mcb, UINT16 event, void *p_data)
         L2CA_DisconnectReq (p_mcb->lcid);
 
         if (p_mcb->restart_required) {
+            tL2CAP_ERTM_INFO *ertm_opt = rfc_cb.port.enable_l2cap_ertm ? &rfc_l2c_etm_opt : NULL;
             /* Start Request was received while disconnecting.  Execute it again */
-            // if ((p_mcb->lcid = L2CA_ConnectReq (BT_PSM_RFCOMM, p_mcb->bd_addr)) == 0) {
-            if ((p_mcb->lcid = L2CA_ErtmConnectReq (BT_PSM_RFCOMM, p_mcb->bd_addr, &rfc_l2c_etm_opt)) == 0) {
+            p_mcb->lcid = L2CA_ErtmConnectReq(BT_PSM_RFCOMM, p_mcb->bd_addr, ertm_opt);
+
+            if (p_mcb->lcid == 0) {
                 PORT_StartCnf (p_mcb, RFCOMM_ERROR);
                 return;
             }
@@ -576,8 +583,10 @@ static void rfc_mx_send_config_req (tRFC_MCB *p_mcb)
     cfg.mtu_present      = TRUE;
     cfg.mtu              = L2CAP_MTU_SIZE;
 
-    cfg.fcr_present = TRUE;
-    cfg.fcr = rfc_l2c_fcr_opts_def;
+    if (rfc_cb.port.enable_l2cap_ertm) {
+        cfg.fcr_present = TRUE;
+        cfg.fcr = rfc_l2c_fcr_opts_def;
+    }
 
     /* Defaults set by memset
         cfg.flush_to_present = FALSE;

+ 2 - 1
components/bt/host/bluedroid/stack/rfcomm/rfc_utils.c

@@ -188,7 +188,8 @@ tRFC_MCB *rfc_alloc_multiplexer_channel (BD_ADDR bd_addr, BOOLEAN is_initiator)
     return (NULL);
 }
 
-void osi_free_fun(void *p){
+void osi_free_fun(void *p)
+{
     osi_free(p);
 }
 /*******************************************************************************

+ 7 - 2
examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/main.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Unlicense OR CC0-1.0
  */
@@ -30,6 +30,7 @@
 #define SPP_SHOW_MODE SPP_SHOW_SPEED    /*Choose show mode: show data or speed*/
 
 static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB;
+static const bool esp_spp_enable_l2cap_ertm = true;
 
 static struct timeval time_new, time_old;
 static long data_num = 0;
@@ -241,7 +242,11 @@ void app_main(void)
         return;
     }
 
-    if ((ret = esp_spp_init(esp_spp_mode)) != ESP_OK) {
+    esp_spp_cfg_t bt_spp_cfg = {
+        .mode = esp_spp_mode,
+        .enable_l2cap_ertm = esp_spp_enable_l2cap_ertm,
+    };
+    if ((ret = esp_spp_enhanced_init(&bt_spp_cfg)) != ESP_OK) {
         ESP_LOGE(SPP_TAG, "%s spp init failed: %s\n", __func__, esp_err_to_name(ret));
         return;
     }

+ 7 - 2
examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/main.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Unlicense OR CC0-1.0
  */
@@ -31,6 +31,7 @@
 #define SPP_SHOW_MODE SPP_SHOW_SPEED    /*Choose show mode: show data or speed*/
 
 static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB;
+static const bool esp_spp_enable_l2cap_ertm = true;
 
 static struct timeval time_new, time_old;
 static long data_num = 0;
@@ -384,7 +385,11 @@ void app_main(void)
         return;
     }
 
-    if ((ret = esp_spp_init(esp_spp_mode)) != ESP_OK) {
+    esp_spp_cfg_t bt_spp_cfg = {
+        .mode = esp_spp_mode,
+        .enable_l2cap_ertm = esp_spp_enable_l2cap_ertm,
+    };
+    if ((ret = esp_spp_enhanced_init(&bt_spp_cfg)) != ESP_OK) {
         ESP_LOGE(SPP_TAG, "%s spp init failed: %s\n", __func__, esp_err_to_name(ret));
         return;
     }

+ 3 - 4
examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/main.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Unlicense OR CC0-1.0
  */
@@ -38,8 +38,6 @@
 #define SPP_SERVER_NAME "SPP_SERVER"
 #define EXAMPLE_DEVICE_NAME "ESP_SPP_ACCEPTOR"
 
-static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_VFS;
-
 static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE;
 static const esp_spp_role_t role_slave = ESP_SPP_ROLE_SLAVE;
 
@@ -250,7 +248,8 @@ void app_main(void)
 
     spp_task_task_start_up();
 
-    if (esp_spp_init(esp_spp_mode) != ESP_OK) {
+    esp_spp_cfg_t bt_spp_cfg = BT_SPP_DEFAULT_CONFIG();
+    if (esp_spp_enhanced_init(&bt_spp_cfg) != ESP_OK) {
         ESP_LOGE(SPP_TAG, "%s spp init failed", __func__);
         return;
     }

+ 4 - 4
examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/main.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Unlicense OR CC0-1.0
  */
@@ -37,8 +37,6 @@
 #define SPP_TAG "SPP_INITIATOR_DEMO"
 #define EXAMPLE_DEVICE_NAME "ESP_SPP_INITIATOR"
 
-static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_VFS;
-
 static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE;
 static const esp_spp_role_t role_master = ESP_SPP_ROLE_MASTER;
 
@@ -332,7 +330,9 @@ void app_main(void)
     }
 
     spp_task_task_start_up();
-    if (esp_spp_init(esp_spp_mode) != ESP_OK) {
+
+    esp_spp_cfg_t bt_spp_cfg = BT_SPP_DEFAULT_CONFIG();
+    if (esp_spp_enhanced_init(&bt_spp_cfg) != ESP_OK) {
         ESP_LOGE(SPP_TAG, "%s spp init failed", __func__);
         return;
     }