You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ja...@apache.org on 2025/12/11 09:05:31 UTC
(mynewt-nimble) 01/02: nimble/host: Add function to remove L2CAP CoC server
This is an automated email from the ASF dual-hosted git repository.
janc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
commit 925e781ee4410af791aa9a4219d0da2e41668657
Author: Szymon Janc <sz...@codecoup.pl>
AuthorDate: Wed Dec 10 15:39:30 2025 +0100
nimble/host: Add function to remove L2CAP CoC server
This allows application to remove previously registered L2CAP CoC
server.
---
nimble/host/include/host/ble_l2cap.h | 13 +++++++
nimble/host/src/ble_l2cap.c | 20 +++++++++-
nimble/host/src/ble_l2cap_coc.c | 69 +++++++++++++++++++----------------
nimble/host/src/ble_l2cap_coc_priv.h | 16 ++++++--
nimble/host/test/src/ble_l2cap_test.c | 24 ++++++++++++
5 files changed, 105 insertions(+), 37 deletions(-)
diff --git a/nimble/host/include/host/ble_l2cap.h b/nimble/host/include/host/ble_l2cap.h
index 32bd41bc8..65329b87a 100644
--- a/nimble/host/include/host/ble_l2cap.h
+++ b/nimble/host/include/host/ble_l2cap.h
@@ -546,6 +546,19 @@ uint16_t ble_l2cap_get_conn_handle(struct ble_l2cap_chan *chan);
int ble_l2cap_create_server(uint16_t psm, uint16_t mtu,
ble_l2cap_event_fn *cb, void *cb_arg);
+/**
+ * @brief Removes an L2CAP server.
+ *
+ * This function removes an L2CAP server with the specified Protocol/Service
+ * Multiplexer (PSM). Existing connections for this PSM are not removed.
+ *
+ * @param psm The Protocol/Service Multiplexer (PSM) for the server.
+ *
+ * @return 0 on success;
+ * A non-zero value on failure.
+ */
+int ble_l2cap_remove_server(uint16_t psm);
+
/**
* @brief Initiate an L2CAP connection.
*
diff --git a/nimble/host/src/ble_l2cap.c b/nimble/host/src/ble_l2cap.c
index c79081eec..0d1b4ebc9 100644
--- a/nimble/host/src/ble_l2cap.c
+++ b/nimble/host/src/ble_l2cap.c
@@ -145,7 +145,25 @@ int
ble_l2cap_create_server(uint16_t psm, uint16_t mtu,
ble_l2cap_event_fn *cb, void *cb_arg)
{
- return ble_l2cap_coc_create_server(psm, mtu, cb, cb_arg);
+ int rc;
+
+ ble_hs_lock();
+ rc = ble_l2cap_coc_create_server_nolock(psm, mtu, cb, cb_arg);
+ ble_hs_unlock();
+
+ return rc;
+}
+
+int
+ble_l2cap_remove_server(uint16_t psm)
+{
+ int rc;
+
+ ble_hs_lock();
+ rc = ble_l2cap_coc_remove_server_nolock(psm);
+ ble_hs_unlock();
+
+ return rc;
}
int
diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c
index a63e50770..6ed30a98f 100644
--- a/nimble/host/src/ble_l2cap_coc.c
+++ b/nimble/host/src/ble_l2cap_coc.c
@@ -52,18 +52,6 @@ static os_membuf_t ble_l2cap_coc_srv_mem[
static struct os_mempool ble_l2cap_coc_srv_pool;
-static void
-ble_l2cap_coc_dbg_assert_srv_not_inserted(struct ble_l2cap_coc_srv *srv)
-{
-#if MYNEWT_VAL(BLE_HS_DEBUG)
- struct ble_l2cap_coc_srv *cur;
-
- STAILQ_FOREACH(cur, &ble_l2cap_coc_srvs, next) {
- BLE_HS_DBG_ASSERT(cur != srv);
- }
-#endif
-}
-
static struct ble_l2cap_coc_srv *
ble_l2cap_coc_srv_alloc(void)
{
@@ -77,12 +65,31 @@ ble_l2cap_coc_srv_alloc(void)
return srv;
}
+static struct ble_l2cap_coc_srv *
+ble_l2cap_coc_srv_find(uint16_t psm)
+{
+ struct ble_l2cap_coc_srv *srv;
+
+ STAILQ_FOREACH(srv, &ble_l2cap_coc_srvs, next) {
+ if (srv->psm == psm) {
+ return srv;
+ }
+ }
+
+ return NULL;
+}
+
int
-ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu,
- ble_l2cap_event_fn *cb, void *cb_arg)
+ble_l2cap_coc_create_server_nolock(uint16_t psm, uint16_t mtu,
+ ble_l2cap_event_fn *cb, void *cb_arg)
{
struct ble_l2cap_coc_srv *srv;
+ srv = ble_l2cap_coc_srv_find(psm);
+ if (srv) {
+ return BLE_HS_EALREADY;
+ }
+
srv = ble_l2cap_coc_srv_alloc();
if (!srv) {
return BLE_HS_ENOMEM;
@@ -93,13 +100,27 @@ ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu,
srv->cb = cb;
srv->cb_arg = cb_arg;
- ble_l2cap_coc_dbg_assert_srv_not_inserted(srv);
-
STAILQ_INSERT_HEAD(&ble_l2cap_coc_srvs, srv, next);
return 0;
}
+int
+ble_l2cap_coc_remove_server_nolock(uint16_t psm)
+{
+ struct ble_l2cap_coc_srv *srv;
+
+ srv = ble_l2cap_coc_srv_find(psm);
+ if (!srv) {
+ return BLE_HS_ENOENT;
+ }
+
+ STAILQ_REMOVE(&ble_l2cap_coc_srvs, srv, ble_l2cap_coc_srv, next);
+
+ os_memblock_put(&ble_l2cap_coc_srv_pool, srv);
+ return 0;
+}
+
static inline void
ble_l2cap_set_used_cid(uint32_t *cid_mask, int bit)
{
@@ -152,22 +173,6 @@ ble_l2cap_coc_get_cid(uint32_t *cid_mask)
return BLE_L2CAP_COC_CID_START + bit;
}
-static struct ble_l2cap_coc_srv *
-ble_l2cap_coc_srv_find(uint16_t psm)
-{
- struct ble_l2cap_coc_srv *cur, *srv;
-
- srv = NULL;
- STAILQ_FOREACH(cur, &ble_l2cap_coc_srvs, next) {
- if (cur->psm == psm) {
- srv = cur;
- break;
- }
- }
-
- return srv;
-}
-
static void
ble_l2cap_event_coc_received_data(struct ble_l2cap_chan *chan,
struct os_mbuf *om)
diff --git a/nimble/host/src/ble_l2cap_coc_priv.h b/nimble/host/src/ble_l2cap_coc_priv.h
index 8a87303fb..673530324 100644
--- a/nimble/host/src/ble_l2cap_coc_priv.h
+++ b/nimble/host/src/ble_l2cap_coc_priv.h
@@ -58,8 +58,9 @@ struct ble_l2cap_coc_srv {
#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0
int ble_l2cap_coc_init(void);
-int ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu,
- ble_l2cap_event_fn *cb, void *cb_arg);
+int ble_l2cap_coc_create_server_nolock(uint16_t psm, uint16_t mtu,
+ ble_l2cap_event_fn *cb, void *cb_arg);
+int ble_l2cap_coc_remove_server_nolock(uint16_t psm);
int ble_l2cap_coc_create_srv_chan(struct ble_hs_conn *conn, uint16_t psm,
struct ble_l2cap_chan **chan);
struct ble_l2cap_chan * ble_l2cap_coc_chan_alloc(struct ble_hs_conn *conn,
@@ -81,8 +82,15 @@ ble_l2cap_coc_init(void) {
}
static inline int
-ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu,
- ble_l2cap_event_fn *cb, void *cb_arg) {
+ble_l2cap_coc_create_server_nolock(uint16_t psm, uint16_t mtu,
+ ble_l2cap_event_fn *cb, void *cb_arg)
+{
+ return BLE_HS_ENOTSUP;
+}
+
+static inline int
+ble_l2cap_coc_remove_server_nolock(uint16_t psm)
+{
return BLE_HS_ENOTSUP;
}
diff --git a/nimble/host/test/src/ble_l2cap_test.c b/nimble/host/test/src/ble_l2cap_test.c
index 5d7729a86..839ac430a 100644
--- a/nimble/host/test/src/ble_l2cap_test.c
+++ b/nimble/host/test/src/ble_l2cap_test.c
@@ -1531,6 +1531,29 @@ TEST_CASE_SELF(ble_l2cap_test_case_sig_coc_conn_multi)
ble_hs_test_util_assert_mbufs_freed(NULL);
}
+TEST_CASE_SELF(ble_l2cap_test_case_server_create_remove)
+{
+ int rc;
+
+ /* Register server */
+ rc = ble_l2cap_create_server(BLE_L2CAP_TEST_PSM, BLE_L2CAP_TEST_COC_MTU,
+ ble_l2cap_test_event, NULL);
+ TEST_ASSERT(rc == 0);
+
+ /* Register second server with same PSM */
+ rc = ble_l2cap_create_server(BLE_L2CAP_TEST_PSM, BLE_L2CAP_TEST_COC_MTU,
+ ble_l2cap_test_event, NULL);
+ TEST_ASSERT(rc == BLE_HS_EALREADY);
+
+ /* remove success */
+ rc = ble_l2cap_remove_server(BLE_L2CAP_TEST_PSM);
+ TEST_ASSERT(rc == 0);
+
+ /* second remove shall fail */
+ rc = ble_l2cap_remove_server(BLE_L2CAP_TEST_PSM);
+ TEST_ASSERT(rc == BLE_HS_ENOENT);
+}
+
TEST_SUITE(ble_l2cap_test_suite)
{
ble_l2cap_test_case_bad_header();
@@ -1562,4 +1585,5 @@ TEST_SUITE(ble_l2cap_test_suite)
ble_l2cap_test_case_coc_send_data_failed_too_big_sdu();
ble_l2cap_test_case_coc_recv_data_succeed();
ble_l2cap_test_case_sig_coc_conn_multi();
+ ble_l2cap_test_case_server_create_remove();
}