diff --git a/components/bt/host/bluedroid/api/esp_l2cap_bt_api.c b/components/bt/host/bluedroid/api/esp_l2cap_bt_api.c index 37a5a5b435..54f79396b3 100644 --- a/components/bt/host/bluedroid/api/esp_l2cap_bt_api.c +++ b/components/bt/host/bluedroid/api/esp_l2cap_bt_api.c @@ -116,16 +116,26 @@ esp_err_t esp_bt_l2cap_stop_srv(uint16_t local_psm) esp_err_t esp_bt_l2cap_vfs_register(void) { + btc_msg_t msg; ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); - return btc_l2cap_vfs_register(); + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_L2CAP; + msg.act = BTC_L2CAP_ACT_VFS_REGISTER; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } esp_err_t esp_bt_l2cap_vfs_unregister(void) { + btc_msg_t msg; ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); - return btc_l2cap_vfs_unregister(); + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_L2CAP; + msg.act = BTC_L2CAP_ACT_VFS_UNREGISTER; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } esp_err_t esp_bt_l2cap_get_protocol_status(esp_bt_l2cap_protocol_status_t *status) diff --git a/components/bt/host/bluedroid/api/include/api/esp_l2cap_bt_api.h b/components/bt/host/bluedroid/api/include/api/esp_l2cap_bt_api.h index 2b73198c6a..7ad90b399b 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_l2cap_bt_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_l2cap_bt_api.h @@ -59,6 +59,8 @@ typedef enum { ESP_BT_L2CAP_START_EVT = 18, /*!< When L2CAP server started, the event comes */ ESP_BT_L2CAP_CL_INIT_EVT = 19, /*!< When L2CAP client initiated a connection, the event comes */ ESP_BT_L2CAP_SRV_STOP_EVT = 36, /*!< When L2CAP server stopped, the event comes */ + ESP_BT_L2CAP_VFS_REGISTER_EVT = 38, /*!< When L2CAP VFS register, the event comes */ + ESP_BT_L2CAP_VFS_UNREGISTER_EVT = 39, /*!< When L2CAP VFS unregister, the event comes */ } esp_bt_l2cap_cb_event_t; /** @@ -125,6 +127,20 @@ typedef union { uint8_t psm; /*!< local psm */ } srv_stop; /*!< L2CAP callback param of ESP_BT_L2CAP_SRV_STOP_EVT */ + /** + * @brief ESP_BT_L2CAP_VFS_REGISTER_EVT + */ + struct l2cap_vfs_register_evt_param { + esp_bt_l2cap_status_t status; /*!< status */ + } vfs_register; /*!< L2CAP callback param of ESP_BT_L2CAP_VFS_REGISTER_EVT */ + + /** + * @brief ESP_BT_L2CAP_VFS_UNREGISTER_EVT + */ + struct l2cap_vfs_unregister_evt_param { + esp_bt_l2cap_status_t status; /*!< status */ + } vfs_unregister; /*!< L2CAP callback param of ESP_BT_L2CAP_VFS_UNREGISTER_EVT */ + } esp_bt_l2cap_cb_param_t; /** @@ -234,6 +250,7 @@ esp_err_t esp_bt_l2cap_stop_srv(uint16_t local_psm); /** * @brief This function is used to register VFS. * Only supports write, read and close. + * When the operation is completed, the callback function will be called with ESP_BT_L2CAP_VFS_REGISTER_EVT. * This function must be called after esp_bt_l2cap_init() successful and before esp_bt_l2cap_deinit(). * * @return @@ -244,6 +261,7 @@ esp_err_t esp_bt_l2cap_vfs_register(void); /** * @brief This function is used to unregister VFS. + * When the operation is completed, the callback function will be called with ESP_BT_L2CAP_VFS_UNREGISTER_EVT. * This function must be called after esp_bt_l2cap_init() successful and before esp_bt_l2cap_deinit(). * * @return diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_l2cap.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_l2cap.h index de741a14b0..bf61852d2f 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_l2cap.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_l2cap.h @@ -24,6 +24,8 @@ typedef enum { BTC_L2CAP_ACT_CONNECT, BTC_L2CAP_ACT_START_SRV, BTC_L2CAP_ACT_STOP_SRV, + BTC_L2CAP_ACT_VFS_REGISTER, + BTC_L2CAP_ACT_VFS_UNREGISTER, } btc_l2cap_act_t; /* btc_l2cap_args_t */ @@ -65,8 +67,7 @@ typedef union { void btc_l2cap_call_handler(btc_msg_t *msg); void btc_l2cap_cb_handler(btc_msg_t *msg); -esp_err_t btc_l2cap_vfs_register(void); -esp_err_t btc_l2cap_vfs_unregister(void); + void btc_l2cap_get_protocol_status(esp_bt_l2cap_protocol_status_t *param); #endif ///defined BTC_L2CAP_INCLUDED && BTC_L2CAP_INCLUDED == TRUE diff --git a/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c b/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c index 0b3a6c2ab9..1c9743fd0c 100644 --- a/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c +++ b/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c @@ -72,7 +72,6 @@ typedef struct { uint8_t service_uuid[16]; } l2cap_slot_t; - typedef struct { l2cap_slot_t *l2cap_slots[BTA_JV_MAX_L2C_CONN + 1]; uint32_t l2cap_slot_id; @@ -103,13 +102,15 @@ static const tL2CAP_ERTM_INFO obex_l2c_etm_opt = OBX_FCR_TX_POOL_ID }; - #if L2CAP_DYNAMIC_MEMORY == FALSE #define is_l2cap_init() (l2cap_local_param.l2cap_slot_mutex != NULL) #else #define is_l2cap_init() (&l2cap_local_param != NULL && l2cap_local_param.l2cap_slot_mutex != NULL) #endif +static void btc_l2cap_vfs_register(void); +static void btc_l2cap_vfs_unregister(void); + static void l2cap_osi_free(void *p) { osi_free(p); @@ -756,6 +757,12 @@ void btc_l2cap_call_handler(btc_msg_t *msg) case BTC_L2CAP_ACT_STOP_SRV: btc_l2cap_stop_srv(arg); break; + case BTC_L2CAP_ACT_VFS_REGISTER: + btc_l2cap_vfs_register(); + break; + case BTC_L2CAP_ACT_VFS_UNREGISTER: + btc_l2cap_vfs_unregister(); + break; default: BTC_TRACE_ERROR("%s: Unhandled event (%d)!\n", __FUNCTION__, msg->act); break; @@ -1199,14 +1206,14 @@ static ssize_t l2cap_vfs_read(int fd, void * dst, size_t size) return item_size; } -esp_err_t btc_l2cap_vfs_register(void) +static void btc_l2cap_vfs_register(void) { - esp_err_t ret = ESP_OK; + esp_bt_l2cap_status_t ret = ESP_BT_L2CAP_SUCCESS; do { if (!is_l2cap_init()) { BTC_TRACE_ERROR("%s L2CAP have not been init\n", __func__); - ret = ESP_FAIL; + ret = ESP_BT_L2CAP_NEED_INIT; break; } @@ -1223,33 +1230,38 @@ esp_err_t btc_l2cap_vfs_register(void) // No FD range is registered here: l2cap_vfs_id is used to register/unregister // file descriptors if (esp_vfs_register_with_id(&vfs, NULL, &l2cap_local_param.l2cap_vfs_id) != ESP_OK) { - ret = ESP_FAIL; + ret = ESP_BT_L2CAP_FAILURE; break; } } while (0); - return ret; + esp_bt_l2cap_cb_param_t param = {0}; + param.vfs_register.status = ret; + btc_l2cap_cb_to_app(ESP_BT_L2CAP_VFS_REGISTER_EVT, ¶m); } -esp_err_t btc_l2cap_vfs_unregister(void) +static void btc_l2cap_vfs_unregister(void) { - esp_err_t ret = ESP_OK; + esp_bt_l2cap_status_t ret = ESP_BT_L2CAP_SUCCESS; + do { if (!is_l2cap_init()) { BTC_TRACE_ERROR("%s L2CAP have not been init\n", __func__); - ret = ESP_FAIL; + ret = ESP_BT_L2CAP_NEED_INIT; break; } if (l2cap_local_param.l2cap_vfs_id != -1) { if (esp_vfs_unregister_with_id(l2cap_local_param.l2cap_vfs_id) != ESP_OK) { - ret = ESP_FAIL; + ret = ESP_BT_L2CAP_FAILURE; } } l2cap_local_param.l2cap_vfs_id = -1; } while (0); - return ret; + esp_bt_l2cap_cb_param_t param = {0}; + param.vfs_unregister.status = ret; + btc_l2cap_cb_to_app(ESP_BT_L2CAP_VFS_UNREGISTER_EVT, ¶m); } void btc_l2cap_get_protocol_status(esp_bt_l2cap_protocol_status_t *param) diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/main/main.c b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/main/main.c index 1af9826dcb..37b42e327b 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -255,7 +255,8 @@ static void esp_bt_l2cap_cb(esp_bt_l2cap_cb_event_t event, esp_bt_l2cap_cb_param case ESP_BT_L2CAP_CLOSE_EVT: case ESP_BT_L2CAP_CL_INIT_EVT: case ESP_BT_L2CAP_START_EVT: - case ESP_BT_L2CAP_SRV_STOP_EVT: { + case ESP_BT_L2CAP_SRV_STOP_EVT: + case ESP_BT_L2CAP_VFS_REGISTER_EVT: { bt_app_work_dispatch(esp_hdl_bt_l2cap_cb_evt, event, param, sizeof(esp_bt_l2cap_cb_param_t), NULL); break; } @@ -306,6 +307,9 @@ static void esp_hdl_bt_l2cap_cb_evt(uint16_t event, void *p_param) case ESP_BT_L2CAP_SRV_STOP_EVT: ESP_LOGI(L2CAP_TAG, "ESP_BT_L2CAP_CLOSE_EVT: status:%d, psm = 0x%x", l2cap_param->srv_stop.status, l2cap_param->srv_stop.psm); break; + case ESP_BT_L2CAP_VFS_REGISTER_EVT: + ESP_LOGI(L2CAP_TAG, "ESP_BT_L2CAP_VFS_REGISTER_EVT: status:%d", l2cap_param->vfs_register.status); + break; default: break; } diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/main/main.c b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/main/main.c index af95f0d97a..1cc2ef34d7 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -163,7 +163,8 @@ static void esp_bt_l2cap_cb(esp_bt_l2cap_cb_event_t event, esp_bt_l2cap_cb_param case ESP_BT_L2CAP_CLOSE_EVT: case ESP_BT_L2CAP_CL_INIT_EVT: case ESP_BT_L2CAP_START_EVT: - case ESP_BT_L2CAP_SRV_STOP_EVT: { + case ESP_BT_L2CAP_SRV_STOP_EVT: + case ESP_BT_L2CAP_VFS_REGISTER_EVT: { bt_app_work_dispatch(esp_hdl_bt_l2cap_cb_evt, event, param, sizeof(esp_bt_l2cap_cb_param_t), NULL); break; } @@ -183,9 +184,8 @@ static void esp_hdl_bt_l2cap_cb_evt(uint16_t event, void *p_param) if (l2cap_param->init.status == ESP_BT_L2CAP_SUCCESS) { ESP_LOGI(L2CAP_TAG, "ESP_BT_L2CAP_INIT_EVT: status:%d", l2cap_param->init.status); esp_bt_l2cap_vfs_register(); - esp_bt_l2cap_start_srv(sec_mask, BT_L2CAP_DYNMIC_PSM); } else { - ESP_LOGI(L2CAP_TAG, "ESP_BT_L2CAP_INIT_EVT: status:%d", l2cap_param->init.status); + ESP_LOGE(L2CAP_TAG, "ESP_BT_L2CAP_INIT_EVT: status:%d", l2cap_param->init.status); } break; case ESP_BT_L2CAP_UNINIT_EVT: @@ -197,7 +197,7 @@ static void esp_hdl_bt_l2cap_cb_evt(uint16_t event, void *p_param) l2cap_param->open.fd, l2cap_param->open.tx_mtu, bda2str(l2cap_param->open.rem_bda, bda_str, sizeof(bda_str))); l2cap_wr_task_start_up(l2cap_read_handle, l2cap_param->open.fd); } else { - ESP_LOGI(L2CAP_TAG, "ESP_BT_L2CAP_OPEN_EVT: status:%d", l2cap_param->open.status); + ESP_LOGE(L2CAP_TAG, "ESP_BT_L2CAP_OPEN_EVT: status:%d", l2cap_param->open.status); } break; case ESP_BT_L2CAP_CLOSE_EVT: @@ -212,12 +212,20 @@ static void esp_hdl_bt_l2cap_cb_evt(uint16_t event, void *p_param) ESP_LOGI(L2CAP_TAG, "ESP_BT_L2CAP_START_EVT: status:%d, hdl:0x%"PRIx32", sec_id:0x%x", l2cap_param->start.status, l2cap_param->start.handle, l2cap_param->start.sec_id); } else { - ESP_LOGI(L2CAP_TAG, "ESP_BT_L2CAP_START_EVT: status:%d", l2cap_param->start.status); + ESP_LOGE(L2CAP_TAG, "ESP_BT_L2CAP_START_EVT: status:%d", l2cap_param->start.status); } break; case ESP_BT_L2CAP_SRV_STOP_EVT: ESP_LOGI(L2CAP_TAG, "ESP_BT_L2CAP_SRV_STOP_EVT: status:%d, psm = 0x%x", l2cap_param->srv_stop.status, l2cap_param->srv_stop.psm); break; + case ESP_BT_L2CAP_VFS_REGISTER_EVT: + if (l2cap_param->vfs_register.status == ESP_BT_L2CAP_SUCCESS) { + ESP_LOGI(L2CAP_TAG, "ESP_BT_L2CAP_VFS_REGISTER_EVT: status:%d", l2cap_param->vfs_register.status); + esp_bt_l2cap_start_srv(sec_mask, BT_L2CAP_DYNMIC_PSM); + } else { + ESP_LOGE(L2CAP_TAG, "ESP_BT_L2CAP_VFS_REGISTER_EVT: status:%d", l2cap_param->vfs_register.status); + } + break; default: break; }