Giter Club home page Giter Club logo

Comments (7)

mickeyl avatar mickeyl commented on June 9, 2024 1

Sure thing, I'll take a go at it.

from mynewt-nimble.

rymanluk avatar rymanluk commented on June 9, 2024

Thanks @mickeyl , Any chance you could send such patch for review?

from mynewt-nimble.

mickeyl avatar mickeyl commented on June 9, 2024

@rymanluk Before I create a pull request, let me run this through you. Does this look reasonable?

diff --git a/nimble/host/include/host/ble_l2cap.h b/nimble/host/include/host/ble_l2cap.h
index aef9682c..bcdd5c71 100644
--- a/nimble/host/include/host/ble_l2cap.h
+++ b/nimble/host/include/host/ble_l2cap.h
@@ -250,7 +250,7 @@ typedef int ble_l2cap_event_fn(struct ble_l2cap_event *event, void *arg);
 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);
-
+int ble_l2cap_remove_server(uint16_t psm);
 int ble_l2cap_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu,
                       struct os_mbuf *sdu_rx,
                       ble_l2cap_event_fn *cb, void *cb_arg);
diff --git a/nimble/host/src/ble_l2cap.c b/nimble/host/src/ble_l2cap.c
index 810d07b3..1773e28a 100644
--- a/nimble/host/src/ble_l2cap.c
+++ b/nimble/host/src/ble_l2cap.c
@@ -150,6 +150,12 @@ ble_l2cap_create_server(uint16_t psm, uint16_t mtu,
     return ble_l2cap_coc_create_server(psm, mtu, cb, cb_arg);
 }

+int
+ble_l2cap_remove_server(uint16_t psm)
+{
+    return ble_l2cap_coc_remove_server(psm);
+}
+
 int
 ble_l2cap_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu,
                   struct os_mbuf *sdu_rx, ble_l2cap_event_fn *cb, void *cb_arg)
diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c
index dada8b0c..0ace7dda 100644
--- a/nimble/host/src/ble_l2cap_coc.c
+++ b/nimble/host/src/ble_l2cap_coc.c
@@ -96,6 +96,22 @@ ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu,
     return 0;
 }

+int
+ble_l2cap_coc_remove_server(uint16_t psm)
+{
+    struct ble_l2cap_coc_srv * srv;
+
+    STAILQ_FOREACH(srv, &ble_l2cap_coc_srvs, next) {
+        if (srv->psm == psm) {
+            STAILQ_REMOVE(&ble_l2cap_coc_srvs, srv, ble_l2cap_coc_srv, next);
+            os_memblock_put(&ble_l2cap_coc_srv_pool, srv);
+            return 0;
+        }
+    }
+
+    return 0;
+}
+
 static inline void
 ble_l2cap_set_used_cid(uint32_t *cid_mask, int bit)
 {
diff --git a/nimble/host/src/ble_l2cap_coc_priv.h b/nimble/host/src/ble_l2cap_coc_priv.h
index 5ebdaa05..21fa7b9d 100644
--- a/nimble/host/src/ble_l2cap_coc_priv.h
+++ b/nimble/host/src/ble_l2cap_coc_priv.h
@@ -57,6 +57,7 @@ struct ble_l2cap_coc_srv {
 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_remove_server(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,

from mynewt-nimble.

rymanluk avatar rymanluk commented on June 9, 2024

Hi @mickeyl

Thanks. I'm just thinking that before server removal we should check if there is no channel allocated for given PSM.

You could use BUSY error when this is detected.
Otherwise it looks good

from mynewt-nimble.

mickeyl avatar mickeyl commented on June 9, 2024

@rymanluk

I'm afraid, I'm a bit out of my depth here. Finding out whether an allocated channel exists would mean I need to iterate over all active connections and all active channels for every connection. The struct ble_l2cap_coc_srv has no helpful pointers there, so I need additional API in ble_hs_conn.c to query an allocated channel by psm?

from mynewt-nimble.

mickeyl avatar mickeyl commented on June 9, 2024

Ok, how about this one:

diff --git a/nimble/host/include/host/ble_l2cap.h b/nimble/host/include/host/ble_l2cap.h
index aef9682c..bcdd5c71 100644
--- a/nimble/host/include/host/ble_l2cap.h
+++ b/nimble/host/include/host/ble_l2cap.h
@@ -250,7 +250,7 @@ typedef int ble_l2cap_event_fn(struct ble_l2cap_event *event, void *arg);
 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);
-
+int ble_l2cap_remove_server(uint16_t psm);
 int ble_l2cap_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu,
                       struct os_mbuf *sdu_rx,
                       ble_l2cap_event_fn *cb, void *cb_arg);
diff --git a/nimble/host/src/ble_hs_conn.c b/nimble/host/src/ble_hs_conn.c
index 01325ad6..f3c95b83 100644
--- a/nimble/host/src/ble_hs_conn.c
+++ b/nimble/host/src/ble_hs_conn.c
@@ -50,6 +50,38 @@ ble_hs_conn_can_alloc(void)
            ble_gatts_conn_can_alloc();
 }
 
+struct ble_l2cap_chan *
+ble_hs_conn_chan_exists_for_psm(struct ble_hs_conn *conn, uint16_t psm)
+{
+    struct ble_l2cap_chan *chan;
+
+    SLIST_FOREACH(chan, &conn->bhc_channels, next) {
+        if (chan->psm == psm) {
+            return chan;
+        }
+    }
+
+    return NULL;
+}
+
+struct ble_hs_conn *
+ble_hs_conn_find_by_psm(uint16_t psm)
+{
+    ble_hs_lock();
+
+    struct ble_hs_conn *conn;
+
+    SLIST_FOREACH(conn, &ble_hs_conns, bhc_next) {
+        if (ble_hs_conn_chan_exists_for_psm(conn, psm)) {
+            ble_hs_unlock();
+            return conn;
+        }
+    }
+
+    ble_hs_unlock();
+    return NULL;
+}
+
 struct ble_l2cap_chan *
 ble_hs_conn_chan_find_by_scid(struct ble_hs_conn *conn, uint16_t cid)
 {
diff --git a/nimble/host/src/ble_hs_conn_priv.h b/nimble/host/src/ble_hs_conn_priv.h
index 0e451194..ce1a4db9 100644
--- a/nimble/host/src/ble_hs_conn_priv.h
+++ b/nimble/host/src/ble_hs_conn_priv.h
@@ -120,6 +120,7 @@ struct ble_hs_conn *ble_hs_conn_find(uint16_t conn_handle);
 struct ble_hs_conn *ble_hs_conn_find_assert(uint16_t conn_handle);
 struct ble_hs_conn *ble_hs_conn_find_by_addr(const ble_addr_t *addr);
 struct ble_hs_conn *ble_hs_conn_find_by_idx(int idx);
+struct ble_hs_conn *ble_hs_conn_find_by_psm(uint16_t psm);
 int ble_hs_conn_exists(uint16_t conn_handle);
 struct ble_hs_conn *ble_hs_conn_first(void);
 struct ble_l2cap_chan *ble_hs_conn_chan_find_by_scid(struct ble_hs_conn *conn,
diff --git a/nimble/host/src/ble_l2cap.c b/nimble/host/src/ble_l2cap.c
index 810d07b3..1773e28a 100644
--- a/nimble/host/src/ble_l2cap.c
+++ b/nimble/host/src/ble_l2cap.c
@@ -150,6 +150,12 @@ ble_l2cap_create_server(uint16_t psm, uint16_t mtu,
     return ble_l2cap_coc_create_server(psm, mtu, cb, cb_arg);
 }
 
+int
+ble_l2cap_remove_server(uint16_t psm)
+{
+    return ble_l2cap_coc_remove_server(psm);
+}
+
 int
 ble_l2cap_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu,
                   struct os_mbuf *sdu_rx, ble_l2cap_event_fn *cb, void *cb_arg)
diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c
index dada8b0c..9cc06991 100644
--- a/nimble/host/src/ble_l2cap_coc.c
+++ b/nimble/host/src/ble_l2cap_coc.c
@@ -96,6 +96,25 @@ ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu,
     return 0;
 }
 
+int
+ble_l2cap_coc_remove_server(uint16_t psm)
+{
+    struct ble_l2cap_coc_srv * srv;
+
+    if (ble_hs_conn_find_by_psm(psm) != NULL) {
+        return BLE_HS_EBUSY;
+    }
+
+    STAILQ_FOREACH(srv, &ble_l2cap_coc_srvs, next) {
+        if (srv->psm == psm) {
+            STAILQ_REMOVE(&ble_l2cap_coc_srvs, srv, ble_l2cap_coc_srv, next);
+            os_memblock_put(&ble_l2cap_coc_srv_pool, srv);
+            return 0;
+        }
+    }
+    return 0;
+}
+
 static inline void
 ble_l2cap_set_used_cid(uint32_t *cid_mask, int bit)
 {
diff --git a/nimble/host/src/ble_l2cap_coc_priv.h b/nimble/host/src/ble_l2cap_coc_priv.h
index 5ebdaa05..21fa7b9d 100644
--- a/nimble/host/src/ble_l2cap_coc_priv.h
+++ b/nimble/host/src/ble_l2cap_coc_priv.h
@@ -57,6 +57,7 @@ struct ble_l2cap_coc_srv {
 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_remove_server(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,

I have added the function ble_hs_conn_find_by_psm (analogue to many other find_by_xyz in the same file) that queries the connections by psm (leveraging another new function ble_hs_conn_chan_exists_for_psm that traverses all the channels of a given connection). If it is present, we return BLE_HS_EBUSY.

from mynewt-nimble.

rymanluk avatar rymanluk commented on June 9, 2024

looks good, please go ahead with PR. Thanks

from mynewt-nimble.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.