mynewt-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ccoll...@apache.org
Subject [3/6] incubator-mynewt-larva git commit: (MYNEWT-69) BLE Host - Initial set of statistics
Date Wed, 17 Feb 2016 23:47:57 GMT
(MYNEWT-69) BLE Host - Initial set of statistics


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/bb97c9c4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/bb97c9c4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/bb97c9c4

Branch: refs/heads/develop
Commit: bb97c9c4043e8437b3b9c878562079ecb6ddfdf2
Parents: ce0b490
Author: Christopher Collins <ccollins476ad@gmail.com>
Authored: Tue Feb 16 17:22:30 2016 -0800
Committer: Christopher Collins <ccollins476ad@gmail.com>
Committed: Wed Feb 17 15:11:07 2016 -0800

----------------------------------------------------------------------
 net/nimble/host/pkg.yml                     |   1 +
 net/nimble/host/src/ble_att.c               | 251 +++++++++++++++++++-
 net/nimble/host/src/ble_att_priv.h          |  62 ++++-
 net/nimble/host/src/ble_att_svr.c           |  89 ++++---
 net/nimble/host/src/ble_gap.c               | 133 ++++++++---
 net/nimble/host/src/ble_gap_priv.h          |  22 ++
 net/nimble/host/src/ble_gatt_priv.h         |  36 +++
 net/nimble/host/src/ble_gattc.c             |  54 ++++-
 net/nimble/host/src/ble_gatts.c             | 285 ++++++++++++++---------
 net/nimble/host/src/ble_hs.c                |  13 +-
 net/nimble/host/src/ble_hs_priv.h           |   1 +
 net/nimble/host/src/test/ble_hs_test_util.c |   2 +
 project/bletiny/src/main.c                  |  20 +-
 13 files changed, 772 insertions(+), 197 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/bb97c9c4/net/nimble/host/pkg.yml
----------------------------------------------------------------------
diff --git a/net/nimble/host/pkg.yml b/net/nimble/host/pkg.yml
index d1045f0..2655faa 100644
--- a/net/nimble/host/pkg.yml
+++ b/net/nimble/host/pkg.yml
@@ -21,6 +21,7 @@ pkg.name: net/nimble/host
 pkg.vers: 0.1 
 pkg.deps:
     - sys/log
+    - sys/stats
     - libs/os
     - libs/util
     - net/nimble

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/bb97c9c4/net/nimble/host/src/ble_att.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att.c b/net/nimble/host/src/ble_att.c
index 467b12f..fc15d1c 100644
--- a/net/nimble/host/src/ble_att.c
+++ b/net/nimble/host/src/ble_att.c
@@ -72,6 +72,8 @@ static const struct ble_att_rx_dispatch_entry ble_att_rx_dispatch[] = {
 #define BLE_ATT_RX_DISPATCH_SZ \
     (sizeof ble_att_rx_dispatch / sizeof ble_att_rx_dispatch[0])
 
+STATS_SECT_DECL(ble_att_stats) ble_att_stats;
+
 /**
  * Lock restrictions: None.
  */
@@ -115,6 +117,240 @@ ble_att_conn_chan_find(uint16_t conn_handle, struct ble_hs_conn **out_conn,
     return 0;
 }
 
+void
+ble_att_inc_tx_stat(uint8_t att_op)
+{
+    switch (att_op) {
+    case BLE_ATT_OP_ERROR_RSP:
+        STATS_INC(ble_att_stats, error_rsp_tx);
+        break;
+
+    case BLE_ATT_OP_MTU_REQ:
+        STATS_INC(ble_att_stats, mtu_req_tx);
+        break;
+
+    case BLE_ATT_OP_MTU_RSP:
+        STATS_INC(ble_att_stats, mtu_rsp_tx);
+        break;
+
+    case BLE_ATT_OP_FIND_INFO_REQ:
+        STATS_INC(ble_att_stats, find_info_req_tx);
+        break;
+
+    case BLE_ATT_OP_FIND_INFO_RSP:
+        STATS_INC(ble_att_stats, find_info_rsp_tx);
+        break;
+
+    case BLE_ATT_OP_FIND_TYPE_VALUE_REQ:
+        STATS_INC(ble_att_stats, find_type_value_req_tx);
+        break;
+
+    case BLE_ATT_OP_FIND_TYPE_VALUE_RSP:
+        STATS_INC(ble_att_stats, find_type_value_rsp_tx);
+        break;
+
+    case BLE_ATT_OP_READ_TYPE_REQ:
+        STATS_INC(ble_att_stats, read_type_req_tx);
+        break;
+
+    case BLE_ATT_OP_READ_TYPE_RSP:
+        STATS_INC(ble_att_stats, read_type_rsp_tx);
+        break;
+
+    case BLE_ATT_OP_READ_REQ:
+        STATS_INC(ble_att_stats, read_req_tx);
+        break;
+
+    case BLE_ATT_OP_READ_RSP:
+        STATS_INC(ble_att_stats, read_rsp_tx);
+        break;
+
+    case BLE_ATT_OP_READ_BLOB_REQ:
+        STATS_INC(ble_att_stats, read_blob_req_tx);
+        break;
+
+    case BLE_ATT_OP_READ_BLOB_RSP:
+        STATS_INC(ble_att_stats, read_blob_rsp_tx);
+        break;
+
+    case BLE_ATT_OP_READ_MULT_REQ:
+        STATS_INC(ble_att_stats, read_mult_req_tx);
+        break;
+
+    case BLE_ATT_OP_READ_MULT_RSP:
+        STATS_INC(ble_att_stats, read_mult_rsp_tx);
+        break;
+
+    case BLE_ATT_OP_READ_GROUP_TYPE_REQ:
+        STATS_INC(ble_att_stats, read_group_type_req_tx);
+        break;
+
+    case BLE_ATT_OP_READ_GROUP_TYPE_RSP:
+        STATS_INC(ble_att_stats, read_group_type_rsp_tx);
+        break;
+
+    case BLE_ATT_OP_WRITE_REQ:
+        STATS_INC(ble_att_stats, write_req_tx);
+        break;
+
+    case BLE_ATT_OP_WRITE_RSP:
+        STATS_INC(ble_att_stats, write_rsp_tx);
+        break;
+
+    case BLE_ATT_OP_PREP_WRITE_REQ:
+        STATS_INC(ble_att_stats, prep_write_req_tx);
+        break;
+
+    case BLE_ATT_OP_PREP_WRITE_RSP:
+        STATS_INC(ble_att_stats, prep_write_rsp_tx);
+        break;
+
+    case BLE_ATT_OP_EXEC_WRITE_REQ:
+        STATS_INC(ble_att_stats, exec_write_req_tx);
+        break;
+
+    case BLE_ATT_OP_EXEC_WRITE_RSP:
+        STATS_INC(ble_att_stats, exec_write_rsp_tx);
+        break;
+
+    case BLE_ATT_OP_NOTIFY_REQ:
+        STATS_INC(ble_att_stats, notify_req_tx);
+        break;
+
+    case BLE_ATT_OP_INDICATE_REQ:
+        STATS_INC(ble_att_stats, indicate_req_tx);
+        break;
+
+    case BLE_ATT_OP_INDICATE_RSP:
+        STATS_INC(ble_att_stats, indicate_rsp_tx);
+        break;
+
+    case BLE_ATT_OP_WRITE_CMD:
+        STATS_INC(ble_att_stats, write_cmd_tx);
+        break;
+
+    default:
+        break;
+    }
+}
+
+static void
+ble_att_inc_rx_stat(uint8_t att_op)
+{
+    switch (att_op) {
+    case BLE_ATT_OP_ERROR_RSP:
+        STATS_INC(ble_att_stats, error_rsp_rx);
+        break;
+
+    case BLE_ATT_OP_MTU_REQ:
+        STATS_INC(ble_att_stats, mtu_req_rx);
+        break;
+
+    case BLE_ATT_OP_MTU_RSP:
+        STATS_INC(ble_att_stats, mtu_rsp_rx);
+        break;
+
+    case BLE_ATT_OP_FIND_INFO_REQ:
+        STATS_INC(ble_att_stats, find_info_req_rx);
+        break;
+
+    case BLE_ATT_OP_FIND_INFO_RSP:
+        STATS_INC(ble_att_stats, find_info_rsp_rx);
+        break;
+
+    case BLE_ATT_OP_FIND_TYPE_VALUE_REQ:
+        STATS_INC(ble_att_stats, find_type_value_req_rx);
+        break;
+
+    case BLE_ATT_OP_FIND_TYPE_VALUE_RSP:
+        STATS_INC(ble_att_stats, find_type_value_rsp_rx);
+        break;
+
+    case BLE_ATT_OP_READ_TYPE_REQ:
+        STATS_INC(ble_att_stats, read_type_req_rx);
+        break;
+
+    case BLE_ATT_OP_READ_TYPE_RSP:
+        STATS_INC(ble_att_stats, read_type_rsp_rx);
+        break;
+
+    case BLE_ATT_OP_READ_REQ:
+        STATS_INC(ble_att_stats, read_req_rx);
+        break;
+
+    case BLE_ATT_OP_READ_RSP:
+        STATS_INC(ble_att_stats, read_rsp_rx);
+        break;
+
+    case BLE_ATT_OP_READ_BLOB_REQ:
+        STATS_INC(ble_att_stats, read_blob_req_rx);
+        break;
+
+    case BLE_ATT_OP_READ_BLOB_RSP:
+        STATS_INC(ble_att_stats, read_blob_rsp_rx);
+        break;
+
+    case BLE_ATT_OP_READ_MULT_REQ:
+        STATS_INC(ble_att_stats, read_mult_req_rx);
+        break;
+
+    case BLE_ATT_OP_READ_MULT_RSP:
+        STATS_INC(ble_att_stats, read_mult_rsp_rx);
+        break;
+
+    case BLE_ATT_OP_READ_GROUP_TYPE_REQ:
+        STATS_INC(ble_att_stats, read_group_type_req_rx);
+        break;
+
+    case BLE_ATT_OP_READ_GROUP_TYPE_RSP:
+        STATS_INC(ble_att_stats, read_group_type_rsp_rx);
+        break;
+
+    case BLE_ATT_OP_WRITE_REQ:
+        STATS_INC(ble_att_stats, write_req_rx);
+        break;
+
+    case BLE_ATT_OP_WRITE_RSP:
+        STATS_INC(ble_att_stats, write_rsp_rx);
+        break;
+
+    case BLE_ATT_OP_PREP_WRITE_REQ:
+        STATS_INC(ble_att_stats, prep_write_req_rx);
+        break;
+
+    case BLE_ATT_OP_PREP_WRITE_RSP:
+        STATS_INC(ble_att_stats, prep_write_rsp_rx);
+        break;
+
+    case BLE_ATT_OP_EXEC_WRITE_REQ:
+        STATS_INC(ble_att_stats, exec_write_req_rx);
+        break;
+
+    case BLE_ATT_OP_EXEC_WRITE_RSP:
+        STATS_INC(ble_att_stats, exec_write_rsp_rx);
+        break;
+
+    case BLE_ATT_OP_NOTIFY_REQ:
+        STATS_INC(ble_att_stats, notify_req_rx);
+        break;
+
+    case BLE_ATT_OP_INDICATE_REQ:
+        STATS_INC(ble_att_stats, indicate_req_rx);
+        break;
+
+    case BLE_ATT_OP_INDICATE_RSP:
+        STATS_INC(ble_att_stats, indicate_rsp_rx);
+        break;
+
+    case BLE_ATT_OP_WRITE_CMD:
+        STATS_INC(ble_att_stats, write_cmd_rx);
+        break;
+
+    default:
+        break;
+    }
+}
+
 /**
  * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
  */
@@ -159,6 +395,8 @@ ble_att_rx(uint16_t conn_handle, struct os_mbuf **om)
         return BLE_HS_EINVAL;
     }
 
+    ble_att_inc_rx_stat(op);
+
     rc = entry->bde_fn(conn_handle, om);
     if (rc != 0) {
         return rc;
@@ -234,8 +472,19 @@ ble_att_create_chan(void)
 /**
  * Lock restrictions: None.
  */
-void
+int
 ble_att_init(void)
 {
+    int rc;
+
     ble_att_preferred_mtu = BLE_ATT_MTU_PREFERRED_DFLT;
+
+    rc = stats_init_and_reg(
+        STATS_HDR(ble_att_stats), STATS_SIZE_INIT_PARMS(ble_att_stats,
+        STATS_SIZE_32), STATS_NAME_INIT_PARMS(ble_att_stats), "ble_att");
+    if (rc != 0) {
+        return BLE_HS_EOS;
+    }
+
+    return 0;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/bb97c9c4/net/nimble/host/src/ble_att_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_priv.h b/net/nimble/host/src/ble_att_priv.h
index 715f718..4ebdea0 100644
--- a/net/nimble/host/src/ble_att_priv.h
+++ b/net/nimble/host/src/ble_att_priv.h
@@ -21,6 +21,7 @@
 #define H_BLE_ATT_PRIV_
 
 #include <inttypes.h>
+#include "stats/stats.h"
 #include "os/queue.h"
 #include "host/ble_att.h"
 struct os_mbuf;
@@ -41,6 +42,64 @@ struct ble_att_exec_write_req;
 struct ble_att_notify_req;
 struct ble_att_indicate_req;
 
+STATS_SECT_START(ble_att_stats)
+    STATS_SECT_ENTRY(error_rsp_rx)
+    STATS_SECT_ENTRY(error_rsp_tx)
+    STATS_SECT_ENTRY(mtu_req_rx)
+    STATS_SECT_ENTRY(mtu_req_tx)
+    STATS_SECT_ENTRY(mtu_rsp_rx)
+    STATS_SECT_ENTRY(mtu_rsp_tx)
+    STATS_SECT_ENTRY(find_info_req_rx)
+    STATS_SECT_ENTRY(find_info_req_tx)
+    STATS_SECT_ENTRY(find_info_rsp_rx)
+    STATS_SECT_ENTRY(find_info_rsp_tx)
+    STATS_SECT_ENTRY(find_type_value_req_rx)
+    STATS_SECT_ENTRY(find_type_value_req_tx)
+    STATS_SECT_ENTRY(find_type_value_rsp_rx)
+    STATS_SECT_ENTRY(find_type_value_rsp_tx)
+    STATS_SECT_ENTRY(read_type_req_rx)
+    STATS_SECT_ENTRY(read_type_req_tx)
+    STATS_SECT_ENTRY(read_type_rsp_rx)
+    STATS_SECT_ENTRY(read_type_rsp_tx)
+    STATS_SECT_ENTRY(read_req_rx)
+    STATS_SECT_ENTRY(read_req_tx)
+    STATS_SECT_ENTRY(read_rsp_rx)
+    STATS_SECT_ENTRY(read_rsp_tx)
+    STATS_SECT_ENTRY(read_blob_req_rx)
+    STATS_SECT_ENTRY(read_blob_req_tx)
+    STATS_SECT_ENTRY(read_blob_rsp_rx)
+    STATS_SECT_ENTRY(read_blob_rsp_tx)
+    STATS_SECT_ENTRY(read_mult_req_rx)
+    STATS_SECT_ENTRY(read_mult_req_tx)
+    STATS_SECT_ENTRY(read_mult_rsp_rx)
+    STATS_SECT_ENTRY(read_mult_rsp_tx)
+    STATS_SECT_ENTRY(read_group_type_req_rx)
+    STATS_SECT_ENTRY(read_group_type_req_tx)
+    STATS_SECT_ENTRY(read_group_type_rsp_rx)
+    STATS_SECT_ENTRY(read_group_type_rsp_tx)
+    STATS_SECT_ENTRY(write_req_rx)
+    STATS_SECT_ENTRY(write_req_tx)
+    STATS_SECT_ENTRY(write_rsp_rx)
+    STATS_SECT_ENTRY(write_rsp_tx)
+    STATS_SECT_ENTRY(prep_write_req_rx)
+    STATS_SECT_ENTRY(prep_write_req_tx)
+    STATS_SECT_ENTRY(prep_write_rsp_rx)
+    STATS_SECT_ENTRY(prep_write_rsp_tx)
+    STATS_SECT_ENTRY(exec_write_req_rx)
+    STATS_SECT_ENTRY(exec_write_req_tx)
+    STATS_SECT_ENTRY(exec_write_rsp_rx)
+    STATS_SECT_ENTRY(exec_write_rsp_tx)
+    STATS_SECT_ENTRY(notify_req_rx)
+    STATS_SECT_ENTRY(notify_req_tx)
+    STATS_SECT_ENTRY(indicate_req_rx)
+    STATS_SECT_ENTRY(indicate_req_tx)
+    STATS_SECT_ENTRY(indicate_rsp_rx)
+    STATS_SECT_ENTRY(indicate_rsp_tx)
+    STATS_SECT_ENTRY(write_cmd_rx)
+    STATS_SECT_ENTRY(write_cmd_tx)
+STATS_SECT_END
+extern STATS_SECT_DECL(ble_att_stats) ble_att_stats;
+
 #define BLE_ATT_MTU_DFLT                23  /* Also the minimum. */
 #define BLE_ATT_MTU_MAX                 240
 #define BLE_ATT_MTU_PREFERRED_DFLT      240
@@ -100,9 +159,10 @@ extern uint8_t ble_att_flat_buf[BLE_ATT_ATTR_MAX_LEN];
 struct ble_l2cap_chan *ble_att_create_chan(void);
 int ble_att_conn_chan_find(uint16_t conn_handle, struct ble_hs_conn **out_conn,
                            struct ble_l2cap_chan **out_chan);
+void ble_att_inc_tx_stat(uint8_t att_op);
 uint16_t ble_att_mtu(uint16_t conn_handle);
 void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu);
-void ble_att_init(void);
+int ble_att_init(void);
 
 
 /*** @svr */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/bb97c9c4/net/nimble/host/src/ble_att_svr.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_svr.c b/net/nimble/host/src/ble_att_svr.c
index b82f55e..9aa109b 100644
--- a/net/nimble/host/src/ble_att_svr.c
+++ b/net/nimble/host/src/ble_att_svr.c
@@ -510,7 +510,7 @@ err:
  * @param rc                    The status indicating whether to transmit an
  *                                  affirmative response or an error.
  * @param txom                  Contains the affirmative response payload.
- * @param err_op                If an error is transmitted, this is the value
+ * @param att_op                If an error is transmitted, this is the value
  *                                  of the error message's op field.
  * @param err_status            If an error is transmitted, this is the value
  *                                  of the error message's status field.
@@ -521,7 +521,7 @@ err:
  */
 static int
 ble_att_svr_tx_rsp(uint16_t conn_handle, int rc, struct os_mbuf *txom,
-                   uint8_t err_op, uint8_t err_status, uint16_t err_handle)
+                   uint8_t att_op, uint8_t err_status, uint16_t err_handle)
 {
     struct ble_l2cap_chan *chan;
     struct ble_hs_conn *conn;
@@ -538,6 +538,7 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, int rc, struct os_mbuf *txom,
     }
 
     if (do_tx) {
+        ble_att_inc_tx_stat(att_op);
         ble_hs_conn_lock();
 
         ble_att_conn_chan_find(conn_handle, &conn, &chan);
@@ -554,7 +555,7 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, int rc, struct os_mbuf *txom,
             }
 
             if (rc != 0) {
-                ble_att_svr_tx_error_rsp(conn, chan, err_op,
+                ble_att_svr_tx_error_rsp(conn, chan, att_op,
                                          err_handle, err_status);
             }
         }
@@ -568,34 +569,47 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, int rc, struct os_mbuf *txom,
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
  */
 static int
-ble_att_svr_tx_mtu_rsp(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
-                       uint8_t op, uint16_t mtu, uint8_t *att_err)
+ble_att_svr_build_mtu_rsp(uint16_t conn_handle, struct os_mbuf **out_txom,
+                          uint8_t *att_err)
 {
     struct ble_att_mtu_cmd cmd;
+    struct ble_l2cap_chan *chan;
+    struct ble_hs_conn *conn;
     struct os_mbuf *txom;
+    uint16_t mtu;
     void *dst;
     int rc;
 
     *att_err = 0; /* Silence unnecessary warning. */
+    txom = NULL;
+
+    ble_hs_conn_lock();
+    ble_att_conn_chan_find(conn_handle, &conn, &chan);
+    if (chan != NULL) {
+        mtu = chan->blc_my_mtu;
+    }
+    ble_hs_conn_unlock();
 
-    assert(op == BLE_ATT_OP_MTU_REQ || op == BLE_ATT_OP_MTU_RSP);
-    assert(mtu >= BLE_ATT_MTU_DFLT);
+    if (chan == NULL) {
+        rc = BLE_HS_ENOTCONN;
+        goto done;
+    }
 
     txom = ble_hs_misc_pkthdr();
     if (txom == NULL) {
         *att_err = BLE_ATT_ERR_INSUFFICIENT_RES;
         rc = BLE_HS_ENOMEM;
-        goto err;
+        goto done;
     }
 
     dst = os_mbuf_extend(txom, BLE_ATT_MTU_CMD_SZ);
     if (dst == NULL) {
         *att_err = BLE_ATT_ERR_INSUFFICIENT_RES;
         rc = BLE_HS_ENOMEM;
-        goto err;
+        goto done;
     }
 
     cmd.bamc_mtu = mtu;
@@ -603,18 +617,10 @@ ble_att_svr_tx_mtu_rsp(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
     rc = ble_att_mtu_rsp_write(dst, BLE_ATT_MTU_CMD_SZ, &cmd);
     assert(rc == 0);
 
-    rc = ble_l2cap_tx(conn, chan, txom);
-    txom = NULL;
-    if (rc != 0) {
-        *att_err = BLE_ATT_ERR_UNLIKELY;
-        goto err;
-    }
-
-    chan->blc_flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
-    return 0;
+    rc = 0;
 
-err:
-    os_mbuf_free_chain(txom);
+done:
+    *out_txom = txom;
     return rc;
 }
 
@@ -627,30 +633,39 @@ ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **om)
     struct ble_att_mtu_cmd cmd;
     struct ble_l2cap_chan *chan;
     struct ble_hs_conn *conn;
+    struct os_mbuf *txom;
     uint8_t att_err;
     int rc;
 
-    ble_hs_conn_lock();
+    txom = NULL;
 
-    rc = ble_att_conn_chan_find(conn_handle, &conn, &chan);
-    if (rc == 0) {
-        rc = ble_att_svr_pullup_req_base(om, BLE_ATT_MTU_CMD_SZ, &att_err);
-        if (rc == 0) {
-            rc = ble_att_mtu_cmd_parse((*om)->om_data, (*om)->om_len, &cmd);
-            assert(rc == 0);
+    rc = ble_att_svr_pullup_req_base(om, BLE_ATT_MTU_CMD_SZ, &att_err);
+    if (rc != 0) {
+        goto done;
+    }
 
-            ble_att_set_peer_mtu(chan, cmd.bamc_mtu);
-            rc = ble_att_svr_tx_mtu_rsp(conn, chan, BLE_ATT_OP_MTU_RSP,
-                                        chan->blc_my_mtu, &att_err);
-        }
-        if (rc != 0) {
-            ble_att_svr_tx_error_rsp(conn, chan, BLE_ATT_OP_MTU_REQ, 0,
-                                     att_err);
-        }
+    rc = ble_att_mtu_cmd_parse((*om)->om_data, (*om)->om_len, &cmd);
+    assert(rc == 0);
+
+    rc = ble_att_svr_build_mtu_rsp(conn_handle, &txom, &att_err);
+    if (rc != 0) {
+        goto done;
     }
 
-    ble_hs_conn_unlock();
+    rc = 0;
 
+done:
+    rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_FIND_INFO_REQ,
+                            att_err, 0);
+    if (rc == 0) {
+        ble_hs_conn_lock();
+        ble_att_conn_chan_find(conn_handle, &conn, &chan);
+        if (chan != NULL) {
+            ble_att_set_peer_mtu(chan, cmd.bamc_mtu);
+            chan->blc_flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
+        }
+        ble_hs_conn_unlock();
+    }
     return rc;
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/bb97c9c4/net/nimble/host/src/ble_gap.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap.c b/net/nimble/host/src/ble_gap.c
index 9a11094..deadd77 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -214,6 +214,13 @@ struct ble_gap_snapshot {
 
 static struct os_mutex ble_gap_mutex;
 
+STATS_SECT_DECL(ble_gap_stats) ble_gap_stats;
+
+STATS_NAME_START(ble_gap_stats)
+    STATS_NAME(ble_gap_stats, connects_slv)
+    STATS_NAME(ble_gap_stats, connects_mst)
+STATS_NAME_END(ble_gap_stats)
+
 /*****************************************************************************
  * $mutex                                                                    *
  *****************************************************************************/
@@ -591,7 +598,7 @@ ble_gap_update_notify(struct ble_gap_update_entry *entry, int status)
     }
 
     ble_gap_call_conn_cb(BLE_GAP_EVENT_CONN_UPDATED, status, &snap, NULL,
-                              NULL);
+                         NULL);
 }
 
 /**
@@ -608,7 +615,7 @@ ble_gap_master_failed(int status)
     switch (ble_gap_master.op) {
     case BLE_GAP_OP_M_DISC:
         ble_gap_call_master_disc_cb(BLE_GAP_EVENT_DISC_FINISHED, status,
-                                         NULL, NULL, 1);
+                                    NULL, NULL, 1);
         break;
 
     case BLE_GAP_OP_M_CONN:
@@ -626,8 +633,7 @@ ble_gap_master_failed(int status)
 static void
 ble_gap_update_entry_remove_free(struct ble_gap_update_entry *entry)
 {
-    SLIST_REMOVE(&ble_gap_update_entries, entry,
-                 ble_gap_update_entry, next);
+    SLIST_REMOVE(&ble_gap_update_entries, entry, ble_gap_update_entry, next);
     ble_gap_update_entry_free(entry);
 }
 
@@ -664,6 +670,8 @@ ble_gap_conn_broken(uint16_t conn_handle)
     ble_gap_unlock();
 
     ble_gattc_connection_broken(conn_handle);
+
+    STATS_INC(ble_gap_stats, disconnects);
 }
 
 /**
@@ -683,6 +691,8 @@ ble_gap_rx_disconn_complete(struct hci_disconn_complete *evt)
 
     ble_hs_misc_assert_no_locks();
 
+    STATS_INC(ble_gap_stats, rx_disconns);
+
     if (evt->status == 0) {
         /* Find the connection that this event refers to. */
         ble_hs_conn_lock();
@@ -727,6 +737,8 @@ ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt)
 
     ble_hs_misc_assert_no_locks();
 
+    STATS_INC(ble_gap_stats, rx_update_completes);
+
     ble_hs_conn_lock();
 
     conn = ble_hs_conn_find(evt->connection_handle);
@@ -952,30 +964,39 @@ ble_gap_master_enqueue(uint8_t state, int in_progress,
 static int
 ble_gap_accept_master_conn(uint8_t addr_type, uint8_t *addr)
 {
+    int rc;
+
     switch (ble_gap_master.op) {
     case BLE_GAP_OP_NULL:
     case BLE_GAP_OP_M_DISC:
-        return BLE_HS_ENOENT;
+        rc = BLE_HS_ENOENT;
+        break;
 
     case BLE_GAP_OP_M_CONN:
         if (ble_gap_master.state != BLE_GAP_STATE_M_ACKED) {
-            return BLE_HS_ENOENT;
-        }
-
-        if (ble_gap_master.conn.addr_type == BLE_GAP_ADDR_TYPE_WL ||
-            (addr_type == ble_gap_master.conn.addr_type &&
-             memcmp(addr, ble_gap_master.conn.addr,
-                    BLE_DEV_ADDR_LEN) == 0)) {
-            return 0;
+            rc = BLE_HS_ENOENT;
+        } else if (ble_gap_master.conn.addr_type == BLE_GAP_ADDR_TYPE_WL ||
+                   (addr_type == ble_gap_master.conn.addr_type &&
+                    memcmp(addr, ble_gap_master.conn.addr,
+                           BLE_DEV_ADDR_LEN) == 0)) {
+            rc = 0;
         } else {
             ble_gap_master_failed(BLE_HS_ECONTROLLER);
-            return BLE_HS_ECONTROLLER;
+            rc = BLE_HS_ECONTROLLER;
         }
+        break;
 
     default:
         assert(0);
-        return BLE_HS_ENOENT;
+        rc = BLE_HS_ENOENT;
+        break;
+    }
+
+    if (rc == 0) {
+        STATS_INC(ble_gap_stats, connects_mst);
     }
+
+    return rc;
 }
 
 /**
@@ -999,31 +1020,43 @@ ble_gap_accept_master_conn(uint8_t addr_type, uint8_t *addr)
 static int
 ble_gap_accept_slave_conn(uint8_t addr_type, uint8_t *addr)
 {
+    int rc;
+
     if (!ble_gap_currently_advertising()) {
-        return BLE_HS_ENOENT;
-    }
+        rc = BLE_HS_ENOENT;
+    } else {
+        switch (ble_gap_slave.op) {
+        case BLE_GAP_OP_NULL:
+        case BLE_GAP_OP_S_NON:
+            rc = BLE_HS_ENOENT;
+            break;
 
-    switch (ble_gap_slave.op) {
-    case BLE_GAP_OP_NULL:
-    case BLE_GAP_OP_S_NON:
-        return BLE_HS_ENOENT;
+        case BLE_GAP_OP_S_UND:
+            rc = 0;
+            break;
 
-    case BLE_GAP_OP_S_UND:
-        return 0;
+        case BLE_GAP_OP_S_DIR:
+            if (ble_gap_slave.dir_addr_type != addr_type ||
+                memcmp(ble_gap_slave.dir_addr, addr, BLE_DEV_ADDR_LEN) != 0) {
 
-    case BLE_GAP_OP_S_DIR:
-        if (ble_gap_slave.dir_addr_type != addr_type ||
-            memcmp(ble_gap_slave.dir_addr, addr, BLE_DEV_ADDR_LEN) != 0) {
+                rc = BLE_HS_ENOENT;
+            } else {
+                rc = 0;
+            }
+            break;
 
-            return BLE_HS_ENOENT;
-        } else {
-            return 0;
+        default:
+            assert(0);
+            rc = BLE_HS_ENOENT;
+            break;
         }
+    }
 
-    default:
-        assert(0);
-        return BLE_HS_ENOENT;
+    if (rc == 0) {
+        STATS_INC(ble_gap_stats, connects_slv);
     }
+
+    return rc;
 }
 
 /**
@@ -1040,6 +1073,8 @@ ble_gap_rx_adv_report(struct ble_hs_adv *adv)
     struct ble_hs_adv_fields fields;
     int rc;
 
+    STATS_INC(ble_gap_stats, rx_adv_reports);
+
     if (ble_gap_master.op      != BLE_GAP_OP_M_DISC ||
         ble_gap_master.state   != BLE_GAP_STATE_M_DISC_ACKED) {
 
@@ -1080,6 +1115,8 @@ ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt)
     int status;
     int rc;
 
+    STATS_INC(ble_gap_stats, rx_conn_completes);
+
     /* Determine if this event refers to a completed connection or a connection
      * in progress.
      */
@@ -1104,7 +1141,7 @@ ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt)
     if (conn != NULL) {
         if (evt->status != 0) {
             ble_gap_call_conn_cb(BLE_GAP_EVENT_CONN, evt->status, &snap,
-                                      NULL, NULL);
+                                 NULL, NULL);
         }
         return 0;
     }
@@ -1228,7 +1265,7 @@ ble_gap_master_timer_exp(void *arg)
     case BLE_GAP_OP_M_DISC:
         /* When a discovery procedure times out, it is not a failure. */
         ble_gap_master_enqueue(BLE_GAP_STATE_M_DISC_DISABLE, 1,
-                                    ble_gap_disc_tx_disable, NULL);
+                               ble_gap_disc_tx_disable, NULL);
         break;
 
     default:
@@ -1292,7 +1329,7 @@ ble_gap_wl_busy(void)
  */
 static int
 ble_gap_wl_enqueue(uint8_t state, int in_progress,
-                        ble_hci_sched_tx_fn *hci_tx_cb, void *cb_arg)
+                   ble_hci_sched_tx_fn *hci_tx_cb, void *cb_arg)
 {
     int rc;
 
@@ -1423,6 +1460,8 @@ ble_gap_wl_set(struct ble_gap_white_entry *white_list,
     int rc;
     int i;
 
+    STATS_INC(ble_gap_stats, wl_sets);
+
     if (white_list_count <= 0) {
         return BLE_HS_EINVAL;
     }
@@ -1509,6 +1548,8 @@ ble_gap_adv_stop(void)
 
     int rc;
 
+    STATS_INC(ble_gap_stats, adv_stops);
+
     /* Do nothing if advertising is already disabled. */
     if (!ble_gap_currently_advertising()) {
         return BLE_HS_EALREADY;
@@ -1891,6 +1932,8 @@ ble_gap_adv_start(uint8_t discoverable_mode, uint8_t connectable_mode,
     uint8_t op;
     int rc;
 
+    STATS_INC(ble_gap_stats, adv_starts);
+
     if (discoverable_mode >= BLE_GAP_DISC_MODE_MAX ||
         connectable_mode >= BLE_GAP_CONN_MODE_MAX) {
 
@@ -1975,6 +2018,8 @@ ble_gap_adv_set_fields(struct ble_hs_adv_fields *adv_fields)
 
     int rc;
 
+    STATS_INC(ble_gap_stats, adv_set_fields);
+
     rc = ble_hs_adv_set_fields(adv_fields, ble_gap_slave.adv_data,
                                &ble_gap_slave.adv_data_len,
                                BLE_GAP_ADV_DATA_LIMIT);
@@ -2143,6 +2188,8 @@ ble_gap_disc(uint32_t duration_ms, uint8_t discovery_mode,
 
     int rc;
 
+    STATS_INC(ble_gap_stats, discovers);
+
     if (discovery_mode != BLE_GAP_DISC_MODE_LTD &&
         discovery_mode != BLE_GAP_DISC_MODE_GEN) {
 
@@ -2288,6 +2335,8 @@ ble_gap_conn_initiate(int addr_type, uint8_t *addr,
 
     int rc;
 
+    STATS_INC(ble_gap_stats, initiates);
+
     if (addr_type != BLE_ADDR_TYPE_PUBLIC &&
         addr_type != BLE_ADDR_TYPE_RANDOM &&
         addr_type != BLE_GAP_ADDR_TYPE_WL) {
@@ -2386,6 +2435,8 @@ ble_gap_terminate(uint16_t conn_handle)
 {
     int rc;
 
+    STATS_INC(ble_gap_stats, terminates);
+
     if (!ble_hs_conn_exists(conn_handle)) {
         return BLE_HS_ENOENT;
     }
@@ -2444,6 +2495,8 @@ ble_gap_cancel(void)
 {
     int rc;
 
+    STATS_INC(ble_gap_stats, cancels);
+
     ble_gap_lock();
 
     if (!ble_gap_master_in_progress()) {
@@ -2750,6 +2803,8 @@ ble_gap_update_params(uint16_t conn_handle, struct ble_gap_upd_params *params)
     struct ble_gap_update_entry *entry;
     int rc;
 
+    STATS_INC(ble_gap_stats, updates);
+
     if (!ble_hs_conn_exists(conn_handle)) {
         return BLE_HS_ENOTCONN;
     }
@@ -2821,6 +2876,14 @@ ble_gap_init(void)
 
     SLIST_INIT(&ble_gap_update_entries);
 
+    rc = stats_init_and_reg(
+        STATS_HDR(ble_gap_stats), STATS_SIZE_INIT_PARMS(ble_gap_stats,
+        STATS_SIZE_32), STATS_NAME_INIT_PARMS(ble_gap_stats), "ble_gap");
+    if (rc != 0) {
+        rc = BLE_HS_EOS;
+        goto err;
+    }
+
     return 0;
 
 err:

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/bb97c9c4/net/nimble/host/src/ble_gap_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap_priv.h b/net/nimble/host/src/ble_gap_priv.h
index c509a76..ec32ff5 100644
--- a/net/nimble/host/src/ble_gap_priv.h
+++ b/net/nimble/host/src/ble_gap_priv.h
@@ -21,6 +21,7 @@
 #define H_BLE_GAP_CONN_
 
 #include <inttypes.h>
+#include "stats/stats.h"
 #include "host/ble_gap.h"
 struct hci_le_conn_upd_complete;
 struct hci_le_conn_param_req;
@@ -29,6 +30,27 @@ struct hci_disconn_complete;
 struct ble_hci_ack;
 struct ble_hs_adv;
 
+STATS_SECT_START(ble_gap_stats)
+    STATS_SECT_ENTRY(disconnects)
+    STATS_SECT_ENTRY(wl_sets)
+    STATS_SECT_ENTRY(adv_stops)
+    STATS_SECT_ENTRY(adv_starts)
+    STATS_SECT_ENTRY(adv_set_fields)
+    STATS_SECT_ENTRY(discovers)
+    STATS_SECT_ENTRY(initiates)
+    STATS_SECT_ENTRY(terminates)
+    STATS_SECT_ENTRY(cancels)
+    STATS_SECT_ENTRY(updates)
+    STATS_SECT_ENTRY(connects_slv)
+    STATS_SECT_ENTRY(connects_mst)
+    STATS_SECT_ENTRY(rx_disconns)
+    STATS_SECT_ENTRY(rx_update_completes)
+    STATS_SECT_ENTRY(rx_adv_reports)
+    STATS_SECT_ENTRY(rx_conn_completes)
+STATS_SECT_END
+
+extern STATS_SECT_DECL(ble_gap_stats) ble_gap_stats;
+
 #define BLE_GAP_CONN_MODE_MAX               3
 #define BLE_GAP_DISC_MODE_MAX               3
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/bb97c9c4/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 51468c4..5d720ca 100644
--- a/net/nimble/host/src/ble_gatt_priv.h
+++ b/net/nimble/host/src/ble_gatt_priv.h
@@ -20,6 +20,7 @@
 #ifndef H_BLE_GATT_PRIV_
 #define H_BLE_GATT_PRIV_
 
+#include "stats/stats.h"
 #include "host/ble_gatt.h"
 struct ble_att_read_type_adata;
 struct ble_att_find_type_value_hinfo;
@@ -27,6 +28,41 @@ struct ble_att_find_info_idata;
 struct ble_att_read_group_type_adata;
 struct ble_att_prep_write_cmd;
 
+STATS_SECT_START(ble_gattc_stats)
+    STATS_SECT_ENTRY(mtu)
+    STATS_SECT_ENTRY(disc_all_svcs)
+    STATS_SECT_ENTRY(disc_svc_uuid)
+    STATS_SECT_ENTRY(find_inc_svcs)
+    STATS_SECT_ENTRY(disc_all_chrs)
+    STATS_SECT_ENTRY(disc_chrs_uuid)
+    STATS_SECT_ENTRY(disc_all_dscs)
+    STATS_SECT_ENTRY(read)
+    STATS_SECT_ENTRY(read_uuid)
+    STATS_SECT_ENTRY(read_long)
+    STATS_SECT_ENTRY(read_mult)
+    STATS_SECT_ENTRY(write_no_rsp)
+    STATS_SECT_ENTRY(write)
+    STATS_SECT_ENTRY(write_long)
+    STATS_SECT_ENTRY(write_reliable)
+    STATS_SECT_ENTRY(notify)
+    STATS_SECT_ENTRY(indicate)
+STATS_SECT_END
+extern STATS_SECT_DECL(ble_gattc_stats) ble_gattc_stats;
+
+STATS_SECT_START(ble_gatts_stats)
+    STATS_SECT_ENTRY(svcs)
+    STATS_SECT_ENTRY(chrs)
+    STATS_SECT_ENTRY(dscs)
+    STATS_SECT_ENTRY(svc_def_reads)
+    STATS_SECT_ENTRY(svc_inc_reads)
+    STATS_SECT_ENTRY(chr_def_reads)
+    STATS_SECT_ENTRY(chr_val_reads)
+    STATS_SECT_ENTRY(chr_val_writes)
+    STATS_SECT_ENTRY(dsc_reads)
+    STATS_SECT_ENTRY(dsc_writes)
+STATS_SECT_END
+extern STATS_SECT_DECL(ble_gatts_stats) ble_gatts_stats;
+
 #define BLE_GATT_CHR_DECL_SZ_16     5
 #define BLE_GATT_CHR_DECL_SZ_128    19
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/bb97c9c4/net/nimble/host/src/ble_gattc.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gattc.c b/net/nimble/host/src/ble_gattc.c
index be876b2..f0ac313 100644
--- a/net/nimble/host/src/ble_gattc.c
+++ b/net/nimble/host/src/ble_gattc.c
@@ -46,7 +46,7 @@
 #define BLE_GATT_OP_DISC_SVC_UUID               2
 #define BLE_GATT_OP_FIND_INC_SVCS               3
 #define BLE_GATT_OP_DISC_ALL_CHRS               4
-#define BLE_GATT_OP_DISC_CHRS_UUID              5
+#define BLE_GATT_OP_DISC_CHR_UUID              5
 #define BLE_GATT_OP_DISC_ALL_DSCS               6
 #define BLE_GATT_OP_READ                        7
 #define BLE_GATT_OP_READ_UUID                   8
@@ -339,7 +339,7 @@ static const struct ble_gattc_rx_adata_entry
 
     { BLE_GATT_OP_FIND_INC_SVCS,    ble_gattc_find_inc_svcs_rx_adata },
     { BLE_GATT_OP_DISC_ALL_CHRS,    ble_gattc_disc_all_chrs_rx_adata },
-    { BLE_GATT_OP_DISC_CHRS_UUID,   ble_gattc_disc_chr_uuid_rx_adata },
+    { BLE_GATT_OP_DISC_CHR_UUID,   ble_gattc_disc_chr_uuid_rx_adata },
     { BLE_GATT_OP_READ_UUID,        ble_gattc_read_uuid_rx_adata },
 };
 
@@ -348,7 +348,7 @@ static const struct ble_gattc_rx_complete_entry
 
     { BLE_GATT_OP_FIND_INC_SVCS,    ble_gattc_find_inc_svcs_rx_complete },
     { BLE_GATT_OP_DISC_ALL_CHRS,    ble_gattc_disc_all_chrs_rx_complete },
-    { BLE_GATT_OP_DISC_CHRS_UUID,   ble_gattc_disc_chr_uuid_rx_complete },
+    { BLE_GATT_OP_DISC_CHR_UUID,   ble_gattc_disc_chr_uuid_rx_complete },
     { BLE_GATT_OP_READ_UUID,        ble_gattc_read_uuid_rx_complete },
 };
 
@@ -396,7 +396,7 @@ static const struct ble_gattc_dispatch_entry {
         .kick_cb = ble_gattc_disc_all_chrs_kick,
         .err_cb = ble_gattc_disc_all_chrs_err,
     },
-    [BLE_GATT_OP_DISC_CHRS_UUID] = {
+    [BLE_GATT_OP_DISC_CHR_UUID] = {
         .kick_cb = ble_gattc_disc_chr_uuid_kick,
         .err_cb = ble_gattc_disc_chr_uuid_err,
     },
@@ -451,6 +451,8 @@ static struct os_mempool ble_gattc_proc_pool;
 
 static struct ble_fsm ble_gattc_fsm;
 
+STATS_SECT_DECL(ble_gattc_stats) ble_gattc_stats;
+
 /*****************************************************************************
  * $mutex                                                                    *
  *****************************************************************************/
@@ -864,6 +866,8 @@ ble_gattc_exchange_mtu(uint16_t conn_handle, ble_gatt_mtu_fn *cb, void *cb_arg)
     struct ble_gattc_proc *proc;
     int rc;
 
+    STATS_INC(ble_gattc_stats, mtu);
+
     ble_gattc_lock();
 
     rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_MTU, &proc);
@@ -1072,6 +1076,8 @@ ble_gattc_disc_all_svcs(uint16_t conn_handle, ble_gatt_disc_svc_fn *cb,
     struct ble_gattc_proc *proc;
     int rc;
 
+    STATS_INC(ble_gattc_stats, disc_all_svcs);
+
     rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_DISC_ALL_SVCS, &proc);
     if (rc != 0) {
         return rc;
@@ -1261,6 +1267,8 @@ ble_gattc_disc_svc_by_uuid(uint16_t conn_handle, void *service_uuid128,
     struct ble_gattc_proc *proc;
     int rc;
 
+    STATS_INC(ble_gattc_stats, disc_svc_uuid);
+
     rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_DISC_SVC_UUID, &proc);
     if (rc != 0) {
         return rc;
@@ -1551,6 +1559,8 @@ ble_gattc_find_inc_svcs(uint16_t conn_handle, uint16_t start_handle,
     struct ble_gattc_proc *proc;
     int rc;
 
+    STATS_INC(ble_gattc_stats, find_inc_svcs);
+
     rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_FIND_INC_SVCS, &proc);
     if (rc != 0) {
         return rc;
@@ -1770,6 +1780,8 @@ ble_gattc_disc_all_chrs(uint16_t conn_handle, uint16_t start_handle,
     struct ble_gattc_proc *proc;
     int rc;
 
+    STATS_INC(ble_gattc_stats, disc_all_chrs);
+
     rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_DISC_ALL_CHRS, &proc);
     if (rc != 0) {
         return rc;
@@ -1996,7 +2008,9 @@ ble_gattc_disc_chrs_by_uuid(uint16_t conn_handle, uint16_t start_handle,
     struct ble_gattc_proc *proc;
     int rc;
 
-    rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_DISC_CHRS_UUID, &proc);
+    STATS_INC(ble_gattc_stats, disc_chrs_uuid);
+
+    rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_DISC_CHR_UUID, &proc);
     if (rc != 0) {
         return rc;
     }
@@ -2189,6 +2203,8 @@ ble_gattc_disc_all_dscs(uint16_t conn_handle, uint16_t chr_def_handle,
     struct ble_gattc_proc *proc;
     int rc;
 
+    STATS_INC(ble_gattc_stats, disc_all_dscs);
+
     rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_DISC_ALL_DSCS, &proc);
     if (rc != 0) {
         return rc;
@@ -2336,6 +2352,8 @@ ble_gattc_read(uint16_t conn_handle, uint16_t attr_handle,
     struct ble_gattc_proc *proc;
     int rc;
 
+    STATS_INC(ble_gattc_stats, read);
+
     rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_READ, &proc);
     if (rc != 0) {
         return rc;
@@ -2518,6 +2536,8 @@ ble_gattc_read_by_uuid(uint16_t conn_handle, uint16_t start_handle,
     struct ble_gattc_proc *proc;
     int rc;
 
+    STATS_INC(ble_gattc_stats, read_uuid);
+
     rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_READ_UUID, &proc);
     if (rc != 0) {
         return rc;
@@ -2701,6 +2721,8 @@ ble_gattc_read_long(uint16_t conn_handle, uint16_t handle,
     struct ble_gattc_proc *proc;
     int rc;
 
+    STATS_INC(ble_gattc_stats, read_long);
+
     rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_READ_LONG, &proc);
     if (rc != 0) {
         return rc;
@@ -2847,6 +2869,8 @@ ble_gattc_read_mult(uint16_t conn_handle, uint16_t *handles,
     struct ble_gattc_proc *proc;
     int rc;
 
+    STATS_INC(ble_gattc_stats, read_mult);
+
     rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_READ_MULT, &proc);
     if (rc != 0) {
         return rc;
@@ -2962,6 +2986,8 @@ ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle, void *value,
     struct ble_gattc_proc *proc;
     int rc;
 
+    STATS_INC(ble_gattc_stats, write_no_rsp);
+
     rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_WRITE_NO_RSP, &proc);
     if (rc != 0) {
         return rc;
@@ -3077,6 +3103,8 @@ ble_gattc_write(uint16_t conn_handle, uint16_t attr_handle, void *value,
     struct ble_gattc_proc *proc;
     int rc;
 
+    STATS_INC(ble_gattc_stats, write);
+
     rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_WRITE, &proc);
     if (rc != 0) {
         return rc;
@@ -3297,6 +3325,8 @@ ble_gattc_write_long(uint16_t conn_handle, uint16_t attr_handle, void *value,
     struct ble_gattc_proc *proc;
     int rc;
 
+    STATS_INC(ble_gattc_stats, write_long);
+
     rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_WRITE_LONG, &proc);
     if (rc != 0) {
         return rc;
@@ -3510,6 +3540,8 @@ ble_gattc_write_reliable(uint16_t conn_handle, struct ble_gatt_attr *attrs,
     struct ble_gattc_proc *proc;
     int rc;
 
+    STATS_INC(ble_gattc_stats, write_reliable);
+
     rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_WRITE_RELIABLE, &proc);
     if (rc != 0) {
         return rc;
@@ -3597,6 +3629,8 @@ ble_gattc_notify_custom(uint16_t conn_handle, struct ble_gatt_attr *attr)
     struct ble_gattc_proc *proc;
     int rc;
 
+    STATS_INC(ble_gattc_stats, notify);
+
     rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_NOTIFY, &proc);
     if (rc != 0) {
         return rc;
@@ -3786,6 +3820,8 @@ ble_gattc_indicate(uint16_t conn_handle, uint16_t chr_val_handle,
     struct ble_gattc_proc *proc;
     int rc;
 
+    STATS_INC(ble_gattc_stats, indicate);
+
     rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_INDICATE, &proc);
     if (rc != 0) {
         return rc;
@@ -4549,6 +4585,14 @@ ble_gattc_init(void)
     os_callout_func_init(&ble_gattc_heartbeat_timer, &ble_hs_evq,
                          ble_gattc_heartbeat, NULL);
 
+    rc = stats_init_and_reg(
+        STATS_HDR(ble_gattc_stats), STATS_SIZE_INIT_PARMS(ble_gattc_stats,
+        STATS_SIZE_32), STATS_NAME_INIT_PARMS(ble_gattc_stats), "ble_gattc");
+    if (rc != 0) {
+        rc = BLE_HS_EOS;
+        goto err;
+    }
+
     return 0;
 
 err:

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/bb97c9c4/net/nimble/host/src/ble_gatts.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatts.c b/net/nimble/host/src/ble_gatts.c
index 109850c..66b3f94 100644
--- a/net/nimble/host/src/ble_gatts.c
+++ b/net/nimble/host/src/ble_gatts.c
@@ -54,6 +54,8 @@ struct ble_gatts_clt_cfg {
 static struct ble_gatts_clt_cfg *ble_gatts_clt_cfgs;
 static int ble_gatts_num_cfgable_chrs;
 
+STATS_SECT_DECL(ble_gatts_stats) ble_gatts_stats;
+
 /**
  * Lock restrictions: None.
  */
@@ -62,9 +64,10 @@ ble_gatts_svc_access(uint16_t conn_handle, uint16_t attr_handle,
                      uint8_t *uuid128, uint8_t op,
                      struct ble_att_svr_access_ctxt *ctxt, void *arg)
 {
+    const struct ble_gatt_svc_def *svc;
     static uint16_t uuid16;
 
-    const struct ble_gatt_svc_def *svc;
+    STATS_INC(ble_gatts_stats, svc_def_reads);
 
     assert(op == BLE_ATT_ACCESS_OP_READ);
 
@@ -96,6 +99,8 @@ ble_gatts_inc_access(uint16_t conn_handle, uint16_t attr_handle,
     const struct ble_gatts_svc_entry *entry;
     uint16_t uuid16;
 
+    STATS_INC(ble_gatts_stats, svc_inc_reads);
+
     assert(op == BLE_ATT_ACCESS_OP_READ);
 
     entry = arg;
@@ -206,6 +211,8 @@ ble_gatts_chr_def_access(uint16_t conn_handle, uint16_t attr_handle,
     const struct ble_gatt_chr_def *chr;
     uint16_t uuid16;
 
+    STATS_INC(ble_gatts_stats, chr_def_reads);
+
     assert(op == BLE_ATT_ACCESS_OP_READ);
 
     chr = arg;
@@ -266,6 +273,23 @@ ble_gatts_chr_op(uint8_t att_op)
     }
 }
 
+static void
+ble_gatts_chr_inc_val_stat(uint8_t gatt_op)
+{
+    switch (gatt_op) {
+    case BLE_GATT_ACCESS_OP_READ_CHR:
+        STATS_INC(ble_gatts_stats, chr_val_reads);
+        break;
+
+    case BLE_GATT_ACCESS_OP_WRITE_CHR:
+        STATS_INC(ble_gatts_stats, chr_val_writes);
+        break;
+
+    default:
+        break;
+    }
+}
+
 /**
  * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
  */
@@ -287,6 +311,8 @@ ble_gatts_chr_val_access(uint16_t conn_handle, uint16_t attr_handle,
     gatt_ctxt.chr_access.data = att_ctxt->attr_data;
     gatt_ctxt.chr_access.len = att_ctxt->data_len;
 
+    ble_gatts_chr_inc_val_stat(gatt_op);
+
     rc = chr->access_cb(conn_handle, attr_handle, gatt_op, &gatt_ctxt,
                         chr->arg);
     if (rc != 0) {
@@ -370,6 +396,131 @@ ble_gatts_register_inc(struct ble_gatts_svc_entry *entry)
 /**
  * Lock restrictions: None.
  */
+static uint8_t
+ble_gatts_dsc_op(uint8_t att_op)
+{
+    switch (att_op) {
+    case BLE_ATT_ACCESS_OP_READ:
+        return BLE_GATT_ACCESS_OP_READ_DSC;
+
+    case BLE_ATT_ACCESS_OP_WRITE:
+        return BLE_GATT_ACCESS_OP_WRITE_DSC;
+
+    default:
+        assert(0);
+        return BLE_GATT_ACCESS_OP_READ_DSC;
+    }
+}
+
+static void
+ble_gatts_dsc_inc_stat(uint8_t gatt_op)
+{
+    switch (gatt_op) {
+    case BLE_GATT_ACCESS_OP_READ_DSC:
+        STATS_INC(ble_gatts_stats, dsc_reads);
+        break;
+
+    case BLE_GATT_ACCESS_OP_WRITE_DSC:
+        STATS_INC(ble_gatts_stats, dsc_writes);
+        break;
+
+    default:
+        break;
+    }
+}
+
+/**
+ * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
+ */
+static int
+ble_gatts_dsc_access(uint16_t conn_handle, uint16_t attr_handle,
+                     uint8_t *uuid128, uint8_t att_op,
+                     struct ble_att_svr_access_ctxt *att_ctxt, void *arg)
+{
+    const struct ble_gatt_dsc_def *dsc;
+    union ble_gatt_access_ctxt gatt_ctxt;
+    uint8_t gatt_op;
+    int rc;
+
+    dsc = arg;
+    assert(dsc != NULL && dsc->access_cb != NULL);
+
+    gatt_op = ble_gatts_dsc_op(att_op);
+    gatt_ctxt.dsc_access.dsc = dsc;
+    gatt_ctxt.dsc_access.data = att_ctxt->attr_data;
+    gatt_ctxt.dsc_access.len = att_ctxt->data_len;
+
+    ble_gatts_dsc_inc_stat(gatt_op);
+
+    rc = dsc->access_cb(conn_handle, attr_handle, gatt_op, &gatt_ctxt,
+                        dsc->arg);
+    if (rc != 0) {
+        return rc;
+    }
+
+    att_ctxt->attr_data = gatt_ctxt.dsc_access.data;
+    att_ctxt->data_len = gatt_ctxt.dsc_access.len;
+
+    return 0;
+}
+
+/**
+ * Lock restrictions: None.
+ */
+static int
+ble_gatts_dsc_is_sane(const struct ble_gatt_dsc_def *dsc)
+{
+    if (dsc->uuid128 == NULL) {
+        return 0;
+    }
+
+    if (dsc->access_cb == NULL) {
+        return 0;
+    }
+
+    return 1;
+}
+
+/**
+ * Lock restrictions: None.
+ */
+static int
+ble_gatts_register_dsc(const struct ble_gatt_dsc_def *dsc,
+                       const struct ble_gatt_chr_def *chr,
+                       uint16_t chr_def_handle,
+                       ble_gatt_register_fn *register_cb, void *cb_arg)
+{
+    union ble_gatt_register_ctxt register_ctxt;
+    uint16_t dsc_handle;
+    int rc;
+
+    if (!ble_gatts_dsc_is_sane(dsc)) {
+        return BLE_HS_EINVAL;
+    }
+
+    rc = ble_att_svr_register(dsc->uuid128, dsc->att_flags, &dsc_handle,
+                              ble_gatts_dsc_access, (void *)dsc);
+    if (rc != 0) {
+        return rc;
+    }
+
+    if (register_cb != NULL) {
+        register_ctxt.dsc_reg.dsc_handle = dsc_handle;
+        register_ctxt.dsc_reg.dsc = dsc;
+        register_ctxt.dsc_reg.chr_def_handle = chr_def_handle;
+        register_ctxt.dsc_reg.chr = chr;
+        register_cb(BLE_GATT_REGISTER_OP_DSC, &register_ctxt, cb_arg);
+    }
+
+    STATS_INC(ble_gatts_stats, dscs);
+
+    return 0;
+
+}
+
+/**
+ * Lock restrictions: None.
+ */
 static int
 ble_gatts_clt_cfg_find_idx(struct ble_gatts_clt_cfg *cfgs,
                            uint16_t chr_def_handle)
@@ -409,13 +560,14 @@ ble_gatts_clt_cfg_find(struct ble_gatts_clt_cfg *cfgs,
  */
 static int
 ble_gatts_clt_cfg_access_locked(struct ble_hs_conn *conn, uint16_t attr_handle,
-                                uint8_t *uuid128, uint8_t op,
+                                uint8_t *uuid128, uint8_t att_op,
                                 struct ble_att_svr_access_ctxt *ctxt,
                                 void *arg)
 {
     struct ble_gatts_clt_cfg *clt_cfg;
     uint16_t chr_def_handle;
     uint16_t flags;
+    uint8_t gatt_op;
 
     static uint8_t buf[2];
 
@@ -434,14 +586,19 @@ ble_gatts_clt_cfg_access_locked(struct ble_hs_conn *conn, uint16_t attr_handle,
         return BLE_ATT_ERR_UNLIKELY;
     }
 
-    switch (op) {
-    case BLE_ATT_ACCESS_OP_READ:
+    gatt_op = ble_gatts_dsc_op(att_op);
+    ble_gatts_dsc_inc_stat(gatt_op);
+
+    switch (gatt_op) {
+    case BLE_GATT_ACCESS_OP_READ_DSC:
+        STATS_INC(ble_gatts_stats, dsc_reads);
         htole16(buf, clt_cfg->flags & ~BLE_GATTS_CLT_CFG_F_RESERVED);
         ctxt->attr_data = buf;
         ctxt->data_len = sizeof buf;
         break;
 
-    case BLE_ATT_ACCESS_OP_WRITE:
+    case BLE_GATT_ACCESS_OP_WRITE_DSC:
+        STATS_INC(ble_gatts_stats, dsc_writes);
         if (ctxt->data_len != 2) {
             return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
         }
@@ -492,110 +649,6 @@ ble_gatts_clt_cfg_access(uint16_t conn_handle, uint16_t attr_handle,
 /**
  * Lock restrictions: None.
  */
-static uint8_t
-ble_gatts_dsc_op(uint8_t att_op)
-{
-    switch (att_op) {
-    case BLE_ATT_ACCESS_OP_READ:
-        return BLE_GATT_ACCESS_OP_READ_DSC;
-
-    case BLE_ATT_ACCESS_OP_WRITE:
-        return BLE_GATT_ACCESS_OP_WRITE_DSC;
-
-    default:
-        assert(0);
-        return BLE_GATT_ACCESS_OP_READ_DSC;
-    }
-}
-
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
-static int
-ble_gatts_dsc_access(uint16_t conn_handle, uint16_t attr_handle,
-                     uint8_t *uuid128, uint8_t att_op,
-                     struct ble_att_svr_access_ctxt *att_ctxt, void *arg)
-{
-    const struct ble_gatt_dsc_def *dsc;
-    union ble_gatt_access_ctxt gatt_ctxt;
-    uint8_t gatt_op;
-    int rc;
-
-    dsc = arg;
-    assert(dsc != NULL && dsc->access_cb != NULL);
-
-    gatt_op = ble_gatts_dsc_op(att_op);
-    gatt_ctxt.dsc_access.dsc = dsc;
-    gatt_ctxt.dsc_access.data = att_ctxt->attr_data;
-    gatt_ctxt.dsc_access.len = att_ctxt->data_len;
-
-    rc = dsc->access_cb(conn_handle, attr_handle, gatt_op, &gatt_ctxt,
-                        dsc->arg);
-    if (rc != 0) {
-        return rc;
-    }
-
-    att_ctxt->attr_data = gatt_ctxt.dsc_access.data;
-    att_ctxt->data_len = gatt_ctxt.dsc_access.len;
-
-    return 0;
-}
-
-/**
- * Lock restrictions: None.
- */
-static int
-ble_gatts_dsc_is_sane(const struct ble_gatt_dsc_def *dsc)
-{
-    if (dsc->uuid128 == NULL) {
-        return 0;
-    }
-
-    if (dsc->access_cb == NULL) {
-        return 0;
-    }
-
-    return 1;
-}
-
-/**
- * Lock restrictions: None.
- */
-static int
-ble_gatts_register_dsc(const struct ble_gatt_dsc_def *dsc,
-                       const struct ble_gatt_chr_def *chr,
-                       uint16_t chr_def_handle,
-                       ble_gatt_register_fn *register_cb, void *cb_arg)
-{
-    union ble_gatt_register_ctxt register_ctxt;
-    uint16_t dsc_handle;
-    int rc;
-
-    if (!ble_gatts_dsc_is_sane(dsc)) {
-        return BLE_HS_EINVAL;
-    }
-
-    rc = ble_att_svr_register(dsc->uuid128, dsc->att_flags, &dsc_handle,
-                              ble_gatts_dsc_access, (void *)dsc);
-    if (rc != 0) {
-        return rc;
-    }
-
-    if (register_cb != NULL) {
-        register_ctxt.dsc_reg.dsc_handle = dsc_handle;
-        register_ctxt.dsc_reg.dsc = dsc;
-        register_ctxt.dsc_reg.chr_def_handle = chr_def_handle;
-        register_ctxt.dsc_reg.chr = chr;
-        register_cb(BLE_GATT_REGISTER_OP_DSC, &register_ctxt, cb_arg);
-    }
-
-    return 0;
-
-}
-
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_register_clt_cfg_dsc(uint16_t *att_handle)
 {
@@ -613,6 +666,8 @@ ble_gatts_register_clt_cfg_dsc(uint16_t *att_handle)
         return rc;
     }
 
+    STATS_INC(ble_gatts_stats, dscs);
+
     return 0;
 }
 
@@ -682,6 +737,8 @@ ble_gatts_register_chr(const struct ble_gatt_chr_def *chr,
         }
     }
 
+    STATS_INC(ble_gatts_stats, chrs);
+
     return 0;
 }
 
@@ -788,6 +845,8 @@ ble_gatts_register_svc(const struct ble_gatt_svc_def *svc,
         }
     }
 
+    STATS_INC(ble_gatts_stats, svcs);
+
     return 0;
 }
 
@@ -1126,6 +1185,14 @@ ble_gatts_init(void)
         }
     }
 
+    rc = stats_init_and_reg(
+        STATS_HDR(ble_gatts_stats), STATS_SIZE_INIT_PARMS(ble_gatts_stats,
+        STATS_SIZE_32), STATS_NAME_INIT_PARMS(ble_gatts_stats), "ble_gatts");
+    if (rc != 0) {
+        rc = BLE_HS_EOS;
+        goto err;
+    }
+
     return 0;
 
 err:

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/bb97c9c4/net/nimble/host/src/ble_hs.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs.c b/net/nimble/host/src/ble_hs.c
index 7ea2404..304ed52 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -20,6 +20,7 @@
 #include <assert.h>
 #include <errno.h>
 #include "bsp/bsp.h"
+#include "stats/stats.h"
 #include "util/tpq.h"
 #include "os/os.h"
 #include "nimble/hci_transport.h"
@@ -260,6 +261,13 @@ ble_hs_init(uint8_t prio, struct ble_hs_cfg *cfg)
     /* Initialize eventq */
     os_eventq_init(&ble_hs_evq);
 
+    /* Initialize stats. */
+    rc = stats_module_init();
+    if (rc != 0) {
+        rc = BLE_HS_EOS;
+        goto err;
+    }
+
     host_hci_init();
 
     rc = ble_hs_conn_init();
@@ -272,7 +280,10 @@ ble_hs_init(uint8_t prio, struct ble_hs_cfg *cfg)
         goto err;
     }
 
-    ble_att_init();
+    rc = ble_att_init();
+    if (rc != 0) {
+        goto err;
+    }
 
     rc = ble_att_svr_init();
     if (rc != 0) {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/bb97c9c4/net/nimble/host/src/ble_hs_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_priv.h b/net/nimble/host/src/ble_hs_priv.h
index e5b9dce..d06b59b 100644
--- a/net/nimble/host/src/ble_hs_priv.h
+++ b/net/nimble/host/src/ble_hs_priv.h
@@ -21,6 +21,7 @@
 #define H_BLE_HS_PRIV_
 
 #include <inttypes.h>
+#include "stats/stats.h"
 #include "log/log.h"
 #include "nimble/nimble_opt.h"
 #include "host/ble_hs.h"

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/bb97c9c4/net/nimble/host/src/test/ble_hs_test_util.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_test_util.c b/net/nimble/host/src/test/ble_hs_test_util.c
index b4b1c78..40f016e 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.c
+++ b/net/nimble/host/src/test/ble_hs_test_util.c
@@ -20,6 +20,7 @@
 #include <string.h>
 #include <errno.h>
 #include <assert.h>
+#include "stats/stats.h"
 #include "nimble/ble.h"
 #include "nimble/hci_common.h"
 #include "testutil/testutil.h"
@@ -409,6 +410,7 @@ ble_hs_test_util_init(void)
     int rc;
 
     os_msys_reset();
+    stats_module_reset();
 
     cfg = ble_hs_cfg_dflt;
     cfg.max_connections = 8;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/bb97c9c4/project/bletiny/src/main.c
----------------------------------------------------------------------
diff --git a/project/bletiny/src/main.c b/project/bletiny/src/main.c
index 4123f07..69fd7ea 100755
--- a/project/bletiny/src/main.c
+++ b/project/bletiny/src/main.c
@@ -22,6 +22,7 @@
 #include <errno.h>
 #include "bsp/bsp.h"
 #include "log/log.h"
+#include "stats/stats.h"
 #include "os/os.h"
 #include "bsp/bsp.h"
 #include "hal/hal_gpio.h"
@@ -1416,6 +1417,17 @@ main(void)
                  NULL, BLETINY_TASK_PRIO, OS_WAIT_FOREVER,
                  bletiny_stack, BLETINY_STACK_SIZE);
 
+    rc = shell_task_init(SHELL_TASK_PRIO, shell_stack, SHELL_TASK_STACK_SIZE,
+                         SHELL_MAX_INPUT_LEN);
+    assert(rc == 0);
+
+    /* Init the console */
+    rc = console_init(shell_console_rx_cb);
+    assert(rc == 0);
+
+    rc = stats_module_init();
+    assert(rc == 0);
+
     /* Initialize the BLE host. */
     cfg = ble_hs_cfg_dflt;
     cfg.max_hci_bufs = 3;
@@ -1432,14 +1444,6 @@ main(void)
     /* Initialize the BLE LL */
     ble_ll_init();
 
-    rc = shell_task_init(SHELL_TASK_PRIO, shell_stack, SHELL_TASK_STACK_SIZE,
-                         SHELL_MAX_INPUT_LEN);
-    assert(rc == 0);
-
-    /* Init the console */
-    rc = console_init(shell_console_rx_cb);
-    assert(rc == 0);
-
     rc = cmd_init();
     assert(rc == 0);
 


Mime
View raw message