You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2015/12/05 04:14:16 UTC

[2/3] incubator-mynewt-larva git commit: GATT Read Characteristic Value procedure.

GATT Read Characteristic Value procedure.


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

Branch: refs/heads/master
Commit: 248ae725435544b4d1c6bde5ea27cd1ce2bc1133
Parents: 3b14a94
Author: Christopher Collins <cc...@gmail.com>
Authored: Fri Dec 4 18:48:03 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Fri Dec 4 19:13:51 2015 -0800

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_gatt.h |   4 +
 net/nimble/host/src/ble_att.c           |   1 +
 net/nimble/host/src/ble_att.h           |  25 ++++---
 net/nimble/host/src/ble_att_clt.c       | 107 ++++++++++++++++++---------
 net/nimble/host/src/ble_att_cmd.h       |   2 +-
 net/nimble/host/src/ble_gatt.c          |  94 ++++++++++++++++++++++-
 6 files changed, 182 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/248ae725/net/nimble/host/include/host/ble_gatt.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_gatt.h b/net/nimble/host/include/host/ble_gatt.h
index 472f753..9fe9266 100644
--- a/net/nimble/host/include/host/ble_gatt.h
+++ b/net/nimble/host/include/host/ble_gatt.h
@@ -32,6 +32,8 @@ int ble_gatt_disc_service_by_uuid(uint16_t conn_handle, void *service_uuid128,
 int ble_gatt_disc_all_chars(uint16_t conn_handle, uint16_t start_handle,
                             uint16_t end_handle, ble_gatt_attr_fn *cb,
                             void *cb_arg);
+int ble_gatt_read(uint16_t conn_handle, uint16_t attr_handle,
+                  ble_gatt_attr_fn *cb, void *cb_arg);
 
 void ble_gatt_rx_err(struct ble_hs_conn *conn, struct ble_att_error_rsp *rsp);
 void ble_gatt_wakeup(void);
@@ -40,6 +42,8 @@ int ble_gatt_mtu(uint16_t conn_handle);
 void ble_gatt_rx_read_type_adata(struct ble_hs_conn *conn,
                                  struct ble_att_clt_adata *adata);
 void ble_gatt_rx_read_type_complete(struct ble_hs_conn *conn, int rc);
+void ble_gatt_rx_read_rsp(struct ble_hs_conn *conn, int status, void *value,
+                          int value_len);
 void ble_gatt_rx_read_group_type_adata(struct ble_hs_conn *conn,
                                        struct ble_att_clt_adata *adata);
 void ble_gatt_rx_read_group_type_complete(struct ble_hs_conn *conn, int rc);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/248ae725/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 bc7000a..be0063f 100644
--- a/net/nimble/host/src/ble_att.c
+++ b/net/nimble/host/src/ble_att.c
@@ -40,6 +40,7 @@ static struct ble_att_rx_dispatch_entry ble_att_rx_dispatch[] = {
     { BLE_ATT_OP_READ_TYPE_REQ,        ble_att_svr_rx_read_type },
     { BLE_ATT_OP_READ_TYPE_RSP,        ble_att_clt_rx_read_type },
     { BLE_ATT_OP_READ_REQ,             ble_att_svr_rx_read },
+    { BLE_ATT_OP_READ_RSP,             ble_att_clt_rx_read },
     { BLE_ATT_OP_READ_GROUP_TYPE_RSP,  ble_att_clt_rx_read_group_type },
     { BLE_ATT_OP_WRITE_REQ,            ble_att_svr_rx_write },
 };

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/248ae725/net/nimble/host/src/ble_att.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att.h b/net/nimble/host/src/ble_att.h
index 0ee0724..f5dfae6 100644
--- a/net/nimble/host/src/ble_att.h
+++ b/net/nimble/host/src/ble_att.h
@@ -124,47 +124,50 @@ int ble_att_svr_register(uint8_t *uuid, uint8_t flags, uint16_t *handle_id,
 
 
 int ble_att_svr_rx_mtu(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
-                       struct os_mbuf **om);
+                       struct os_mbuf **rxom);
 int ble_att_svr_rx_find_info(struct ble_hs_conn *conn,
                              struct ble_l2cap_chan *chan,
-                             struct os_mbuf **om);
+                             struct os_mbuf **rxom);
 int ble_att_svr_rx_find_type_value(struct ble_hs_conn *conn,
                                    struct ble_l2cap_chan *chan,
-                                   struct os_mbuf **om);
+                                   struct os_mbuf **rxom);
 int ble_att_svr_rx_read_type(struct ble_hs_conn *conn,
                              struct ble_l2cap_chan *chan,
-                             struct os_mbuf **om);
+                             struct os_mbuf **rxom);
 int ble_att_svr_rx_read(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
-                        struct os_mbuf **om);
+                        struct os_mbuf **rxom);
 int ble_att_svr_rx_write(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
-                         struct os_mbuf **om);
+                         struct os_mbuf **rxom);
 int ble_att_svr_init(void);
 
 /*** @clt */
 int ble_att_clt_rx_error(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
-                         struct os_mbuf **om);
+                         struct os_mbuf **rxom);
 int ble_att_clt_tx_mtu(struct ble_hs_conn *conn,
                        struct ble_att_mtu_cmd *req);
 int ble_att_clt_rx_mtu(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
-                       struct os_mbuf **om);
+                       struct os_mbuf **rxom);
 int ble_att_clt_tx_read(struct ble_hs_conn *conn,
                         struct ble_att_read_req *req);
+int ble_att_clt_rx_read(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
+                        struct os_mbuf **rxom);
 int ble_att_clt_tx_read_type(struct ble_hs_conn *conn,
                              struct ble_att_read_type_req *req,
                              void *uuid128);
 int ble_att_clt_rx_read_type(struct ble_hs_conn *conn,
                              struct ble_l2cap_chan *chan,
-                             struct os_mbuf **om);
+                             struct os_mbuf **rxom);
 int ble_att_clt_tx_read_group_type(struct ble_hs_conn *conn,
                                    struct ble_att_read_group_type_req *req,
                                    void *uuid128);
 int ble_att_clt_rx_read_group_type(struct ble_hs_conn *conn,
                                    struct ble_l2cap_chan *chan,
-                                   struct os_mbuf **om);
+                                   struct os_mbuf **rxom);
 int ble_att_clt_tx_find_info(struct ble_hs_conn *conn,
                              struct ble_att_find_info_req *req);
 int ble_att_clt_rx_find_info(struct ble_hs_conn *conn,
-                             struct ble_l2cap_chan *chan, struct os_mbuf **om);
+                             struct ble_l2cap_chan *chan,
+                             struct os_mbuf **rxom);
 int ble_att_clt_tx_find_type_value(struct ble_hs_conn *conn,
                                    struct ble_att_find_type_value_req *req,
                                    void *attribute_value, int value_len);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/248ae725/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 fd8a300..e675405 100644
--- a/net/nimble/host/src/ble_att_clt.c
+++ b/net/nimble/host/src/ble_att_clt.c
@@ -249,43 +249,6 @@ ble_att_clt_rx_find_info(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
 }
 
 int
-ble_att_clt_tx_read(struct ble_hs_conn *conn, struct ble_att_read_req *req)
-{
-    struct ble_l2cap_chan *chan;
-    struct os_mbuf *txom;
-    int rc;
-
-    txom = NULL;
-
-    if (req->barq_handle == 0) {
-        rc = EINVAL;
-        goto err;
-    }
-
-    rc = ble_att_clt_prep_req(conn, &chan, &txom, BLE_ATT_READ_REQ_SZ);
-    if (rc != 0) {
-        goto err;
-    }
-
-    rc = ble_att_read_req_write(txom->om_data, txom->om_len, req);
-    if (rc != 0) {
-        goto err;
-    }
-
-    rc = ble_l2cap_tx(chan, txom);
-    txom = NULL;
-    if (rc != 0) {
-        goto err;
-    }
-
-    return 0;
-
-err:
-    os_mbuf_free_chain(txom);
-    return rc;
-}
-
-int
 ble_att_clt_tx_read_type(struct ble_hs_conn *conn,
                          struct ble_att_read_type_req *req,
                          void *uuid128)
@@ -439,6 +402,76 @@ err:
     return rc;
 }
 
+int
+ble_att_clt_tx_read(struct ble_hs_conn *conn, struct ble_att_read_req *req)
+{
+    struct ble_l2cap_chan *chan;
+    struct os_mbuf *txom;
+    int rc;
+
+    txom = NULL;
+
+    if (req->barq_handle == 0) {
+        rc = EINVAL;
+        goto err;
+    }
+
+    rc = ble_att_clt_prep_req(conn, &chan, &txom, BLE_ATT_READ_REQ_SZ);
+    if (rc != 0) {
+        goto err;
+    }
+
+    rc = ble_att_read_req_write(txom->om_data, txom->om_len, req);
+    if (rc != 0) {
+        goto err;
+    }
+
+    rc = ble_l2cap_tx(chan, txom);
+    txom = NULL;
+    if (rc != 0) {
+        goto err;
+    }
+
+    return 0;
+
+err:
+    os_mbuf_free_chain(txom);
+    return rc;
+}
+
+int
+ble_att_clt_rx_read(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
+                    struct os_mbuf **rxom)
+{
+    void *value;
+    int value_len;
+    int rc;
+
+    value = NULL;
+    value_len = 0;
+
+    /* Reponse consists of a one-byte opcode (already verified) and a variable
+     * length Attribute Value field.  Strip the opcode from the response.
+     */
+    os_mbuf_adj(*rxom, BLE_ATT_READ_RSP_BASE_SZ);
+
+    /* Pass the Attribute Value field to the GATT. */
+    *rxom = os_mbuf_pullup(*rxom, OS_MBUF_PKTLEN(*rxom));
+    if (*rxom == NULL) {
+        rc = EMSGSIZE;
+        goto done;
+    }
+
+    value_len = (*rxom)->om_len;
+    value = (*rxom)->om_data;
+
+    rc = 0;
+
+done:
+    ble_gatt_rx_read_rsp(conn, rc, value, value_len);
+    return rc;
+}
+
 static int
 ble_att_clt_parse_group_attribute_data(struct os_mbuf **om, int data_len,
                                  struct ble_att_clt_adata *adata)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/248ae725/net/nimble/host/src/ble_att_cmd.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_cmd.h b/net/nimble/host/src/ble_att_cmd.h
index ea9c907..0676a0a 100644
--- a/net/nimble/host/src/ble_att_cmd.h
+++ b/net/nimble/host/src/ble_att_cmd.h
@@ -160,7 +160,7 @@ struct ble_att_read_req {
  * | Attribute Opcode                   | 1                 |
  * | Attribute Value                    | 0 to (ATT_MTU-1)  |
  */
-#define BLE_ATT_READ_RSP_MIN_SZ          1
+#define BLE_ATT_READ_RSP_BASE_SZ        1
 
 /**
  * | Parameter                          | Size (octets)     |

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/248ae725/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 977db4e..9490b18 100644
--- a/net/nimble/host/src/ble_gatt.c
+++ b/net/nimble/host/src/ble_gatt.c
@@ -62,6 +62,12 @@ struct ble_gatt_entry {
             ble_gatt_attr_fn *cb;
             void *cb_arg;
         } disc_all_chars;
+
+        struct {
+            uint16_t handle;
+            ble_gatt_attr_fn *cb;
+            void *cb_arg;
+        } read;
     };
 };
 
@@ -70,7 +76,8 @@ struct ble_gatt_entry {
 #define BLE_GATT_OP_DISC_ALL_SERVICES           1
 #define BLE_GATT_OP_DISC_SERVICE_UUID           2
 #define BLE_GATT_OP_DISC_ALL_CHARS              3
-#define BLE_GATT_OP_MAX                         4
+#define BLE_GATT_OP_READ                        4
+#define BLE_GATT_OP_MAX                         5
 
 typedef int ble_gatt_kick_fn(struct ble_gatt_entry *entry);
 typedef int ble_gatt_rx_err_fn(struct ble_gatt_entry *entry,
@@ -81,6 +88,7 @@ static int ble_gatt_kick_mtu(struct ble_gatt_entry *entry);
 static int ble_gatt_kick_disc_all_services(struct ble_gatt_entry *entry);
 static int ble_gatt_kick_disc_service_uuid(struct ble_gatt_entry *entry);
 static int ble_gatt_kick_disc_all_chars(struct ble_gatt_entry *entry);
+static int ble_gatt_kick_read(struct ble_gatt_entry *entry);
 
 static int ble_gatt_rx_err_disc_all_services(struct ble_gatt_entry *entry,
                                              struct ble_hs_conn *conn,
@@ -91,6 +99,9 @@ static int ble_gatt_rx_err_disc_service_uuid(struct ble_gatt_entry *entry,
 static int ble_gatt_rx_err_disc_all_chars(struct ble_gatt_entry *entry,
                                           struct ble_hs_conn *conn,
                                           struct ble_att_error_rsp *rsp);
+static int ble_gatt_rx_err_read(struct ble_gatt_entry *entry,
+                                struct ble_hs_conn *conn,
+                                struct ble_att_error_rsp *rsp);
 
 struct ble_gatt_dispatch_entry {
     ble_gatt_kick_fn *kick_cb;
@@ -102,7 +113,7 @@ static const struct ble_gatt_dispatch_entry
 
     [BLE_GATT_OP_MTU] = {
         .kick_cb = ble_gatt_kick_mtu,
-        .rx_err_cb = NULL,
+        .rx_err_cb = NULL, // XXX
     },
     [BLE_GATT_OP_DISC_ALL_SERVICES] = {
         .kick_cb = ble_gatt_kick_disc_all_services,
@@ -116,6 +127,10 @@ static const struct ble_gatt_dispatch_entry
         .kick_cb = ble_gatt_kick_disc_all_chars,
         .rx_err_cb = ble_gatt_rx_err_disc_all_chars,
     },
+    [BLE_GATT_OP_READ] = {
+        .kick_cb = ble_gatt_kick_read,
+        .rx_err_cb = ble_gatt_rx_err_read,
+    },
 };
 
 #define BLE_GATT_ENTRY_F_PENDING    0x01
@@ -374,6 +389,27 @@ ble_gatt_kick_disc_all_chars(struct ble_gatt_entry *entry)
     return 0;
 }
 
+static int
+ble_gatt_kick_read(struct ble_gatt_entry *entry)
+{
+    struct ble_att_read_req req;
+    struct ble_hs_conn *conn;
+    int rc;
+
+    conn = ble_hs_conn_find(entry->conn_handle);
+    if (conn == NULL) {
+        return ENOTCONN;
+    }
+
+    req.barq_handle = entry->read.handle;
+    rc = ble_att_clt_tx_read(conn, &req);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}
+
 void
 ble_gatt_wakeup(void)
 {
@@ -469,6 +505,17 @@ ble_gatt_rx_err_disc_all_chars(struct ble_gatt_entry *entry,
     return 0;
 }
 
+static int
+ble_gatt_rx_err_read(struct ble_gatt_entry *entry,
+                     struct ble_hs_conn *conn,
+                     struct ble_att_error_rsp *rsp)
+{
+    entry->read.cb(conn->bhc_handle, rsp->baep_error_code, NULL,
+                   entry->disc_all_chars.cb_arg);
+
+    return 0;
+}
+
 void
 ble_gatt_rx_err(struct ble_hs_conn *conn, struct ble_att_error_rsp *rsp)
 {
@@ -699,6 +746,30 @@ ble_gatt_rx_read_type_complete(struct ble_hs_conn *conn, int rc)
     }
 }
 
+void
+ble_gatt_rx_read_rsp(struct ble_hs_conn *conn, int status, void *value,
+                     int value_len)
+{
+    struct ble_gatt_entry *entry;
+    struct ble_gatt_entry *prev;
+    struct ble_gatt_attr attr;
+
+    entry = ble_gatt_find(conn->bhc_handle, BLE_GATT_OP_READ, 1, &prev);
+    if (entry == NULL) {
+        /* Not expecting a response from this device. */
+        return;
+    }
+
+    attr.handle = entry->read.handle;
+    attr.value_len = value_len;
+    attr.value = value;
+
+    entry->read.cb(conn->bhc_handle, status, &attr, entry->read.cb_arg);
+
+    /* The read operation only has a single request / response exchange. */
+    ble_gatt_entry_remove_free(entry, prev);
+}
+
 int
 ble_gatt_disc_all_services(uint16_t conn_handle, ble_gatt_disc_service_fn *cb,
                            void *cb_arg)
@@ -760,6 +831,25 @@ ble_gatt_disc_all_chars(uint16_t conn_handle, uint16_t start_handle,
 }
 
 int
+ble_gatt_read(uint16_t conn_handle, uint16_t attr_handle,
+              ble_gatt_attr_fn *cb, void *cb_arg)
+{
+    struct ble_gatt_entry *entry;
+    int rc;
+
+    rc = ble_gatt_new_entry(conn_handle, &entry);
+    if (rc != 0) {
+        return rc;
+    }
+    entry->op = BLE_GATT_OP_READ;
+    entry->read.handle = attr_handle;
+    entry->read.cb = cb;
+    entry->read.cb_arg = cb_arg;
+
+    return 0;
+}
+
+int
 ble_gatt_init(void)
 {
     int rc;