mynewt-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ccoll...@apache.org
Subject [1/6] incubator-mynewt-larva git commit: GATT retries in case of congestion or OOM.
Date Fri, 18 Dec 2015 18:37:04 GMT
Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master 958a0aeda -> aa8482eba


GATT retries in case of congestion or OOM.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/7092b08b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/7092b08b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/7092b08b

Branch: refs/heads/master
Commit: 7092b08b3640e7d4b07951203a64035f08239d99
Parents: fac9b74
Author: Christopher Collins <ccollins476ad@gmail.com>
Authored: Thu Dec 17 16:28:20 2015 -0800
Committer: Christopher Collins <ccollins476ad@gmail.com>
Committed: Fri Dec 18 10:36:51 2015 -0800

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_hs.h |   1 +
 net/nimble/host/src/ble_att_clt.c     |   7 ++
 net/nimble/host/src/ble_gatt.c        | 130 ++++++++++++++++++++++++++++-
 net/nimble/host/src/ble_gatt_priv.h   |   1 +
 net/nimble/host/src/ble_hs_conn.c     |   7 ++
 net/nimble/host/src/ble_hs_conn.h     |   1 +
 6 files changed, 145 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/7092b08b/net/nimble/host/include/host/ble_hs.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_hs.h b/net/nimble/host/include/host/ble_hs.h
index 79ca8ae..4978904 100644
--- a/net/nimble/host/include/host/ble_hs.h
+++ b/net/nimble/host/include/host/ble_hs.h
@@ -30,6 +30,7 @@
 #define BLE_HS_EATT                     9
 #define BLE_HS_EBADDATA                 10
 #define BLE_HS_EOS                      11
+#define BLE_HS_ECONGESTED               12
 
 int ble_hs_init(uint8_t prio);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/7092b08b/net/nimble/host/src/ble_att_clt.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_clt.c b/net/nimble/host/src/ble_att_clt.c
index da7ce80..797b2e0 100644
--- a/net/nimble/host/src/ble_att_clt.c
+++ b/net/nimble/host/src/ble_att_clt.c
@@ -34,9 +34,16 @@ ble_att_clt_prep_req(struct ble_hs_conn *conn, struct ble_l2cap_chan **chan,
     void *buf;
     int rc;
 
+    *txom = NULL;
+
     *chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
     assert(*chan != NULL);
 
+    if (!ble_hs_conn_can_tx(conn)) {
+        rc = BLE_HS_ECONGESTED;
+        goto err;
+    }
+
     *txom = ble_att_get_pkthdr();
     if (*txom == NULL) {
         rc = BLE_HS_ENOMEM;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/7092b08b/net/nimble/host/src/ble_gatt.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatt.c b/net/nimble/host/src/ble_gatt.c
index 3908a99..f45410c 100644
--- a/net/nimble/host/src/ble_gatt.c
+++ b/net/nimble/host/src/ble_gatt.c
@@ -76,6 +76,8 @@ struct ble_gatt_entry {
     };
 };
 
+#define BLE_GATT_RETX_PERIOD                    1000 /* Milliseconds. */
+
 #define BLE_GATT_OP_NONE                        UINT8_MAX
 #define BLE_GATT_OP_MTU                         0
 #define BLE_GATT_OP_DISC_ALL_SERVICES           1
@@ -86,6 +88,8 @@ struct ble_gatt_entry {
 #define BLE_GATT_OP_WRITE                       6
 #define BLE_GATT_OP_MAX                         7
 
+static struct os_callout_func ble_gatt_retx_timer;
+
 typedef int ble_gatt_kick_fn(struct ble_gatt_entry *entry);
 typedef void ble_gatt_err_fn(struct ble_gatt_entry *entry,
                              uint8_t ble_hs_status, uint8_t att_status);
@@ -154,6 +158,8 @@ static const struct ble_gatt_dispatch_entry
 
 #define BLE_GATT_ENTRY_F_PENDING    0x01
 #define BLE_GATT_ENTRY_F_EXPECTING  0x02
+#define BLE_GATT_ENTRY_F_CONGESTED  0x04
+#define BLE_GATT_ENTRY_F_NO_MEM     0x08
 
 #define BLE_GATT_NUM_ENTRIES          4
 static void *ble_gatt_entry_mem;
@@ -311,6 +317,60 @@ ble_gatt_new_entry(uint16_t conn_handle, uint8_t op,
     return 0;
 }
 
+static int
+ble_gatt_entry_can_pend(struct ble_gatt_entry *entry)
+{
+    return !(entry->flags & (BLE_GATT_ENTRY_F_CONGESTED |
+                             BLE_GATT_ENTRY_F_NO_MEM |
+                             BLE_GATT_ENTRY_F_EXPECTING));
+}
+
+static void
+ble_gatt_retx_timer_ensure(void)
+{
+    int rc;
+
+    rc = os_callout_reset(&ble_gatt_retx_timer.cf_c,
+                          BLE_GATT_RETX_PERIOD * OS_TICKS_PER_SEC / 1000);
+    assert(rc == 0);
+}
+
+static void
+ble_gatt_retx_timer_exp(void *arg)
+{
+    struct ble_gatt_entry *entry;
+
+    STAILQ_FOREACH(entry, &ble_gatt_list, next) {
+        if (entry->flags & BLE_GATT_ENTRY_F_NO_MEM) {
+            entry->flags &= ~BLE_GATT_ENTRY_F_NO_MEM;
+            if (ble_gatt_entry_can_pend(entry)) {
+                ble_gatt_entry_set_pending(entry);
+            }
+        }
+    }
+}
+
+/**
+ * @return                      1 if the transmit should be postponed; else 0.
+ */
+static int
+ble_gatt_tx_postpone_chk(struct ble_gatt_entry *entry, int rc)
+{
+    switch (rc) {
+    case BLE_HS_ECONGESTED:
+        entry->flags |= BLE_GATT_ENTRY_F_CONGESTED;
+        return 1;
+
+    case BLE_HS_ENOMEM:
+        entry->flags |= BLE_GATT_ENTRY_F_NO_MEM;
+        ble_gatt_retx_timer_ensure();
+        return 1;
+
+    default:
+        return 0;
+    }
+}
+
 /*****************************************************************************
  * @mtu                                                                      *
  *****************************************************************************/
@@ -357,6 +417,10 @@ ble_gatt_kick_mtu(struct ble_gatt_entry *entry)
     return 0;
 
 err:
+    if (ble_gatt_tx_postpone_chk(entry, rc)) {
+        return BLE_HS_EAGAIN;
+    }
+
     ble_gatt_mtu_cb(entry, rc, 0, 0);
     return rc;
 }
@@ -447,6 +511,10 @@ ble_gatt_kick_disc_all_services(struct ble_gatt_entry *entry)
     return 0;
 
 err:
+    if (ble_gatt_tx_postpone_chk(entry, rc)) {
+        return BLE_HS_EAGAIN;
+    }
+
     ble_gatt_disc_all_services_cb(entry, rc, 0, NULL);
     return rc;
 }
@@ -607,6 +675,10 @@ ble_gatt_kick_disc_service_uuid(struct ble_gatt_entry *entry)
     return 0;
 
 err:
+    if (ble_gatt_tx_postpone_chk(entry, rc)) {
+        return BLE_HS_EAGAIN;
+    }
+
     ble_gatt_disc_service_uuid_cb(entry, rc, 0, NULL);
     return rc;
 }
@@ -744,6 +816,10 @@ ble_gatt_kick_disc_all_chars(struct ble_gatt_entry *entry)
     return 0;
 
 err:
+    if (ble_gatt_tx_postpone_chk(entry, rc)) {
+        return BLE_HS_EAGAIN;
+    }
+
     ble_gatt_disc_all_chars_cb(entry, rc, 0, NULL);
     return rc;
 }
@@ -903,6 +979,10 @@ ble_gatt_kick_read(struct ble_gatt_entry *entry)
     return 0;
 
 err:
+    if (ble_gatt_tx_postpone_chk(entry, rc)) {
+        return BLE_HS_EAGAIN;
+    }
+
     ble_gatt_read_cb(entry, rc, 0, NULL);
     return rc;
 }
@@ -1004,6 +1084,10 @@ ble_gatt_kick_write_no_rsp(struct ble_gatt_entry *entry)
     return 1;
 
 err:
+    if (ble_gatt_tx_postpone_chk(entry, rc)) {
+        return BLE_HS_EAGAIN;
+    }
+
     ble_gatt_write_cb(entry, rc, 0);
     return rc;
 }
@@ -1056,6 +1140,10 @@ ble_gatt_kick_write(struct ble_gatt_entry *entry)
     return 0;
 
 err:
+    if (ble_gatt_tx_postpone_chk(entry, rc)) {
+        return BLE_HS_EAGAIN;
+    }
+
     ble_gatt_write_cb(entry, rc, 0);
     return rc;
 }
@@ -1127,10 +1215,19 @@ ble_gatt_wakeup(void)
         if (entry->flags & BLE_GATT_ENTRY_F_PENDING) {
             dispatch = ble_gatt_dispatch_get(entry->op);
             rc = dispatch->kick_cb(entry);
-            if (rc == 0) {
+            switch (rc) {
+            case 0:
+                /* Transmit succeeded.  Response expected. */
                 ble_gatt_entry_set_expecting(entry, prev);
                 /* Current entry got moved to back; old prev still valid. */
-            } else {
+                break;
+
+            case BLE_HS_EAGAIN:
+                /* Transmit failed due to resource shortage.  Reschedule. */
+                break;
+
+            default:
+                /* Transmit failed.  Abort procedure. */
                 ble_gatt_entry_remove_free(entry, prev);
                 /* Current entry removed; old prev still valid. */
             }
@@ -1163,6 +1260,11 @@ ble_gatt_rx_err(uint16_t conn_handle, struct ble_att_error_rsp *rsp)
     ble_gatt_entry_remove_free(entry, prev);
 }
 
+/**
+ * Called when a BLE connection ends.  Frees all GATT resources associated with
+ * the connection and cancels all relevant pending and in-progress GATT
+ * procedures.
+ */
 void
 ble_gatt_connection_broken(uint16_t conn_handle)
 {
@@ -1183,6 +1285,27 @@ ble_gatt_connection_broken(uint16_t conn_handle)
     }
 }
 
+/**
+ * Called when a BLE connection transitions into a transmittable state.  Wakes
+ * up all congested GATT procedures associated with the connection.
+ */
+void
+ble_gatt_connection_txable(uint16_t conn_handle)
+{
+    struct ble_gatt_entry *entry;
+
+    STAILQ_FOREACH(entry, &ble_gatt_list, next) {
+        if (entry->conn_handle == conn_handle &&
+            entry->flags & BLE_GATT_ENTRY_F_CONGESTED) {
+
+            entry->flags &= ~BLE_GATT_ENTRY_F_CONGESTED;
+            if (ble_gatt_entry_can_pend(entry)) {
+                ble_gatt_entry_set_pending(entry);
+            }
+        }
+    }
+}
+
 int
 ble_gatt_init(void)
 {
@@ -1209,6 +1332,9 @@ ble_gatt_init(void)
 
     STAILQ_INIT(&ble_gatt_list);
 
+    os_callout_func_init(&ble_gatt_retx_timer, &ble_hs_evq,
+                         ble_gatt_retx_timer_exp, NULL);
+
     return 0;
 
 err:

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/7092b08b/net/nimble/host/src/ble_gatt_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatt_priv.h b/net/nimble/host/src/ble_gatt_priv.h
index 2ea6587..6eb1dfd 100644
--- a/net/nimble/host/src/ble_gatt_priv.h
+++ b/net/nimble/host/src/ble_gatt_priv.h
@@ -37,6 +37,7 @@ void ble_gatt_rx_find_type_value_hinfo(struct ble_hs_conn *conn,
                                        struct ble_att_clt_adata *adata);
 void ble_gatt_rx_find_type_value_complete(struct ble_hs_conn *conn, int rc);
 void ble_gatt_rx_write_rsp(struct ble_hs_conn *conn);
+void ble_gatt_connection_txable(uint16_t conn_handle);
 void ble_gatt_connection_broken(uint16_t conn_handle);
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/7092b08b/net/nimble/host/src/ble_hs_conn.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn.c b/net/nimble/host/src/ble_hs_conn.c
index 1dddb3a..8bb6e12 100644
--- a/net/nimble/host/src/ble_hs_conn.c
+++ b/net/nimble/host/src/ble_hs_conn.c
@@ -153,6 +153,13 @@ ble_hs_conn_rx_num_completed_pkts(uint16_t handle, uint16_t num_pkts)
     conn->bhc_outstanding_pkts -= num_pkts;
 }
 
+int
+ble_hs_conn_can_tx(struct ble_hs_conn *conn)
+{
+    /* XXX: Ensure number of outstanding packets isn't too great. */
+    return 1;
+}
+
 static void
 ble_hs_conn_free_mem(void)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/7092b08b/net/nimble/host/src/ble_hs_conn.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn.h b/net/nimble/host/src/ble_hs_conn.h
index a8b2dfb..8b623b7 100644
--- a/net/nimble/host/src/ble_hs_conn.h
+++ b/net/nimble/host/src/ble_hs_conn.h
@@ -44,6 +44,7 @@ struct ble_hs_conn *ble_hs_conn_first(void);
 struct ble_l2cap_chan *ble_hs_conn_chan_find(struct ble_hs_conn *conn,
                                              uint16_t cid);
 void ble_hs_conn_rx_num_completed_pkts(uint16_t handle, uint16_t num_pkts);
+int ble_hs_conn_can_tx(struct ble_hs_conn *conn);
 int ble_hs_conn_init(void);
 
 #endif


Mime
View raw message