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/09 23:08:27 UTC
[2/5] incubator-mynewt-larva git commit: Organize GATT code by
procedure.
Organize GATT code by 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/2844303f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/2844303f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/2844303f
Branch: refs/heads/master
Commit: 2844303f5e4a30dfce116dc3da2e4f75a9ab4514
Parents: d85dc98
Author: Christopher Collins <cc...@gmail.com>
Authored: Wed Dec 9 11:43:27 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Wed Dec 9 11:43:27 2015 -0800
----------------------------------------------------------------------
net/nimble/host/src/ble_gatt.c | 546 +++++++++++++++++++-----------------
1 file changed, 296 insertions(+), 250 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/2844303f/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 55e4b0b..9b5dfc5 100644
--- a/net/nimble/host/src/ble_gatt.c
+++ b/net/nimble/host/src/ble_gatt.c
@@ -139,6 +139,10 @@ static struct os_mempool ble_gatt_entry_pool;
static STAILQ_HEAD(, ble_gatt_entry) ble_gatt_list;
+/*****************************************************************************
+ * @entry *
+ *****************************************************************************/
+
static const struct ble_gatt_dispatch_entry *
ble_gatt_dispatch_get(uint8_t op)
{
@@ -282,6 +286,10 @@ ble_gatt_new_entry(uint16_t conn_handle, struct ble_gatt_entry **entry)
return 0;
}
+/*****************************************************************************
+ * @mtu *
+ *****************************************************************************/
+
static int
ble_gatt_kick_mtu(struct ble_gatt_entry *entry)
{
@@ -307,136 +315,86 @@ ble_gatt_kick_mtu(struct ble_gatt_entry *entry)
return 0;
}
-static int
-ble_gatt_kick_disc_all_services(struct ble_gatt_entry *entry)
+void
+ble_gatt_rx_mtu(struct ble_hs_conn *conn, uint16_t chan_mtu)
{
- struct ble_att_read_group_type_req req;
- struct ble_hs_conn *conn;
- uint8_t uuid128[16];
- int rc;
-
- conn = ble_hs_conn_find(entry->conn_handle);
- if (conn == NULL) {
- return ENOTCONN;
- }
-
- rc = ble_hs_uuid_from_16bit(BLE_ATT_UUID_PRIMARY_SERVICE, uuid128);
- assert(rc == 0);
+ struct ble_gatt_entry *entry;
+ struct ble_gatt_entry *prev;
- req.bagq_start_handle = entry->disc_all_services.prev_handle + 1;
- req.bagq_end_handle = 0xffff;
- rc = ble_att_clt_tx_read_group_type(conn, &req, uuid128);
- if (rc != 0) {
- return rc;
+ entry = ble_gatt_find(conn->bhc_handle, BLE_GATT_OP_MTU, 1, &prev);
+ if (entry == NULL) {
+ /* Not expecting a response from this device. */
+ return;
}
- return 0;
+ /* XXX: Call success callback. */
+ ble_gatt_entry_remove_free(entry, prev);
}
-static int
-ble_gatt_kick_disc_service_uuid(struct ble_gatt_entry *entry)
+int
+ble_gatt_exchange_mtu(uint16_t conn_handle)
{
- struct ble_att_find_type_value_req req;
- struct ble_hs_conn *conn;
+ struct ble_gatt_entry *entry;
int rc;
- conn = ble_hs_conn_find(entry->conn_handle);
- if (conn == NULL) {
- return ENOTCONN;
- }
-
- req.bavq_start_handle = entry->disc_service_uuid.prev_handle + 1;
- req.bavq_end_handle = 0xffff;
- req.bavq_attr_type = BLE_ATT_UUID_PRIMARY_SERVICE;
-
- rc = ble_att_clt_tx_find_type_value(conn, &req,
- entry->disc_service_uuid.service_uuid,
- 16);
+ rc = ble_gatt_new_entry(conn_handle, &entry);
if (rc != 0) {
return rc;
}
+ entry->op = BLE_GATT_OP_MTU;
return 0;
}
+/*****************************************************************************
+ * @discover all services *
+ *****************************************************************************/
+
static int
-ble_gatt_kick_disc_all_chars(struct ble_gatt_entry *entry)
+ble_gatt_disc_all_services_cb(struct ble_gatt_entry *entry, int status,
+ struct ble_gatt_service *service)
{
- struct ble_att_read_type_req req;
- struct ble_hs_conn *conn;
- uint8_t uuid128[16];
int rc;
- conn = ble_hs_conn_find(entry->conn_handle);
- if (conn == NULL) {
- return ENOTCONN;
- }
-
- rc = ble_hs_uuid_from_16bit(BLE_ATT_UUID_CHARACTERISTIC, uuid128);
- assert(rc == 0);
-
- req.batq_start_handle = entry->disc_all_chars.prev_handle + 1;
- req.batq_end_handle = entry->disc_all_chars.end_handle;
-
- rc = ble_att_clt_tx_read_type(conn, &req, uuid128);
- if (rc != 0) {
- return rc;
+ if (entry->disc_all_services.cb == NULL) {
+ rc = 0;
+ } else {
+ rc = entry->disc_all_services.cb(entry->conn_handle, status, service,
+ entry->disc_all_services.cb_arg);
}
- return 0;
+ return rc;
}
static int
-ble_gatt_kick_read(struct ble_gatt_entry *entry)
+ble_gatt_kick_disc_all_services(struct ble_gatt_entry *entry)
{
- struct ble_att_read_req req;
+ struct ble_att_read_group_type_req req;
struct ble_hs_conn *conn;
+ uint8_t uuid128[16];
int rc;
conn = ble_hs_conn_find(entry->conn_handle);
if (conn == NULL) {
- return ENOTCONN;
+ rc = ENOTCONN;
+ goto err;
}
- req.barq_handle = entry->read.handle;
- rc = ble_att_clt_tx_read(conn, &req);
+ rc = ble_hs_uuid_from_16bit(BLE_ATT_UUID_PRIMARY_SERVICE, uuid128);
+ assert(rc == 0);
+
+ req.bagq_start_handle = entry->disc_all_services.prev_handle + 1;
+ req.bagq_end_handle = 0xffff;
+ rc = ble_att_clt_tx_read_group_type(conn, &req, uuid128);
if (rc != 0) {
- return rc;
+ goto err;
}
return 0;
-}
-void
-ble_gatt_wakeup(void)
-{
- const struct ble_gatt_dispatch_entry *dispatch;
- struct ble_gatt_entry *entry;
- struct ble_gatt_entry *prev;
- struct ble_gatt_entry *next;
- struct ble_gatt_entry *last;
- int rc;
-
- last = STAILQ_LAST(&ble_gatt_list, ble_gatt_entry, next);
-
- prev = NULL;
- entry = STAILQ_FIRST(&ble_gatt_list);
- while (prev != last) {
- next = STAILQ_NEXT(entry, next);
-
- if (entry->flags & BLE_GATT_ENTRY_F_PENDING) {
- dispatch = ble_gatt_dispatch_get(entry->op);
- rc = dispatch->kick_cb(entry);
- if (rc == 0) {
- ble_gatt_entry_set_expecting(entry, prev);
- } else {
- ble_gatt_entry_remove_free(entry, prev);
- }
- }
-
- prev = entry;
- entry = next;
- }
+err:
+ ble_gatt_disc_all_services_cb(entry, rc, NULL);
+ return rc;
}
static int
@@ -454,116 +412,12 @@ ble_gatt_rx_err_disc_all_services(struct ble_gatt_entry *entry,
status = rsp->baep_error_code;
}
- entry->disc_all_services.cb(conn->bhc_handle, status, NULL,
- entry->disc_all_services.cb_arg);
-
- return 0;
-}
-
-static int
-ble_gatt_rx_err_disc_service_uuid(struct ble_gatt_entry *entry,
- struct ble_hs_conn *conn,
- struct ble_att_error_rsp *rsp)
-{
- uint8_t status;
-
- if (rsp->baep_error_code == BLE_ATT_ERR_ATTR_NOT_FOUND) {
- /* Discovery is complete. */
- status = 0;
- } else {
- /* Discovery failure. */
- status = rsp->baep_error_code;
- }
-
- entry->disc_service_uuid.cb(conn->bhc_handle, status, NULL,
- entry->disc_service_uuid.cb_arg);
-
- return 0;
-}
-
-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)
-{
- uint8_t status;
-
- if (rsp->baep_error_code == BLE_ATT_ERR_ATTR_NOT_FOUND) {
- /* Discovery is complete. */
- status = 0;
- } else {
- /* Discovery failure. */
- status = rsp->baep_error_code;
- }
-
- entry->disc_all_chars.cb(conn->bhc_handle, status, NULL,
- entry->disc_all_chars.cb_arg);
-
- 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);
+ ble_gatt_disc_all_services_cb(entry, status, NULL);
return 0;
}
void
-ble_gatt_rx_err(struct ble_hs_conn *conn, struct ble_att_error_rsp *rsp)
-{
- const struct ble_gatt_dispatch_entry *dispatch;
- struct ble_gatt_entry *entry;
- struct ble_gatt_entry *prev;
-
- entry = ble_gatt_find(conn->bhc_handle, BLE_GATT_OP_NONE, 1, &prev);
- if (entry == NULL) {
- /* Not expecting a response from this device. */
- return;
- }
-
- dispatch = ble_gatt_dispatch_get(entry->op);
- dispatch->rx_err_cb(entry, conn, rsp);
-
- ble_gatt_entry_remove_free(entry, prev);
-}
-
-int
-ble_gatt_exchange_mtu(uint16_t conn_handle)
-{
- 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_MTU;
-
- return 0;
-}
-
-void
-ble_gatt_rx_mtu(struct ble_hs_conn *conn, uint16_t chan_mtu)
-{
- struct ble_gatt_entry *entry;
- struct ble_gatt_entry *prev;
-
- entry = ble_gatt_find(conn->bhc_handle, BLE_GATT_OP_MTU, 1, &prev);
- if (entry == NULL) {
- /* Not expecting a response from this device. */
- return;
- }
-
- /* XXX: Call success callback. */
- ble_gatt_entry_remove_free(entry, prev);
-}
-
-void
ble_gatt_rx_read_group_type_adata(struct ble_hs_conn *conn,
struct ble_att_clt_adata *adata)
{
@@ -607,8 +461,7 @@ ble_gatt_rx_read_group_type_adata(struct ble_hs_conn *conn,
rc = 0;
done:
- cbrc = entry->disc_all_services.cb(conn->bhc_handle, rc, &service,
- entry->disc_all_services.cb_arg);
+ cbrc = ble_gatt_disc_all_services_cb(entry, rc, &service);
if (rc != 0 || cbrc != 0) {
ble_gatt_entry_remove_free(entry, prev);
}
@@ -629,8 +482,7 @@ ble_gatt_rx_read_group_type_complete(struct ble_hs_conn *conn, int rc)
if (rc != 0 || entry->disc_all_services.prev_handle == 0xffff) {
/* Error or all services discovered. */
- entry->disc_all_services.cb(conn->bhc_handle, rc, NULL,
- entry->disc_all_services.cb_arg);
+ ble_gatt_disc_all_services_cb(entry, rc, NULL);
ble_gatt_entry_remove_free(entry, prev);
} else {
/* Send follow-up request. */
@@ -638,6 +490,76 @@ ble_gatt_rx_read_group_type_complete(struct ble_hs_conn *conn, int rc)
}
}
+int
+ble_gatt_disc_all_services(uint16_t conn_handle, ble_gatt_disc_service_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_DISC_ALL_SERVICES;
+ entry->disc_all_services.prev_handle = 0x0000;
+ entry->disc_all_services.cb = cb;
+ entry->disc_all_services.cb_arg = cb_arg;
+
+ return 0;
+}
+
+/*****************************************************************************
+ * @discover service by uuid *
+ *****************************************************************************/
+
+static int
+ble_gatt_kick_disc_service_uuid(struct ble_gatt_entry *entry)
+{
+ struct ble_att_find_type_value_req req;
+ struct ble_hs_conn *conn;
+ int rc;
+
+ conn = ble_hs_conn_find(entry->conn_handle);
+ if (conn == NULL) {
+ return ENOTCONN;
+ }
+
+ req.bavq_start_handle = entry->disc_service_uuid.prev_handle + 1;
+ req.bavq_end_handle = 0xffff;
+ req.bavq_attr_type = BLE_ATT_UUID_PRIMARY_SERVICE;
+
+ rc = ble_att_clt_tx_find_type_value(conn, &req,
+ entry->disc_service_uuid.service_uuid,
+ 16);
+ if (rc != 0) {
+ return rc;
+ }
+
+ return 0;
+}
+
+static int
+ble_gatt_rx_err_disc_service_uuid(struct ble_gatt_entry *entry,
+ struct ble_hs_conn *conn,
+ struct ble_att_error_rsp *rsp)
+{
+ uint8_t status;
+
+ if (rsp->baep_error_code == BLE_ATT_ERR_ATTR_NOT_FOUND) {
+ /* Discovery is complete. */
+ status = 0;
+ } else {
+ /* Discovery failure. */
+ status = rsp->baep_error_code;
+ }
+
+ entry->disc_service_uuid.cb(conn->bhc_handle, status, NULL,
+ entry->disc_service_uuid.cb_arg);
+
+ return 0;
+}
+
void
ble_gatt_rx_find_type_value_hinfo(struct ble_hs_conn *conn,
struct ble_att_clt_adata *adata)
@@ -689,6 +611,78 @@ ble_gatt_rx_find_type_value_complete(struct ble_hs_conn *conn, int rc)
}
}
+int
+ble_gatt_disc_service_by_uuid(uint16_t conn_handle, void *service_uuid128,
+ ble_gatt_disc_service_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_DISC_SERVICE_UUID;
+ memcpy(entry->disc_service_uuid.service_uuid, service_uuid128, 16);
+ entry->disc_service_uuid.prev_handle = 0x0000;
+ entry->disc_service_uuid.cb = cb;
+ entry->disc_service_uuid.cb_arg = cb_arg;
+
+ return 0;
+}
+
+/*****************************************************************************
+ * @discover all characteristics *
+ *****************************************************************************/
+
+static int
+ble_gatt_kick_disc_all_chars(struct ble_gatt_entry *entry)
+{
+ struct ble_att_read_type_req req;
+ struct ble_hs_conn *conn;
+ uint8_t uuid128[16];
+ int rc;
+
+ conn = ble_hs_conn_find(entry->conn_handle);
+ if (conn == NULL) {
+ return ENOTCONN;
+ }
+
+ rc = ble_hs_uuid_from_16bit(BLE_ATT_UUID_CHARACTERISTIC, uuid128);
+ assert(rc == 0);
+
+ req.batq_start_handle = entry->disc_all_chars.prev_handle + 1;
+ req.batq_end_handle = entry->disc_all_chars.end_handle;
+
+ rc = ble_att_clt_tx_read_type(conn, &req, uuid128);
+ if (rc != 0) {
+ return rc;
+ }
+
+ return 0;
+}
+
+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)
+{
+ uint8_t status;
+
+ if (rsp->baep_error_code == BLE_ATT_ERR_ATTR_NOT_FOUND) {
+ /* Discovery is complete. */
+ status = 0;
+ } else {
+ /* Discovery failure. */
+ status = rsp->baep_error_code;
+ }
+
+ entry->disc_all_chars.cb(conn->bhc_handle, status, NULL,
+ entry->disc_all_chars.cb_arg);
+
+ return 0;
+}
+
void
ble_gatt_rx_read_type_adata(struct ble_hs_conn *conn,
struct ble_att_clt_adata *adata)
@@ -743,6 +737,63 @@ ble_gatt_rx_read_type_complete(struct ble_hs_conn *conn, int rc)
}
}
+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)
+{
+ 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_DISC_ALL_CHARS;
+ entry->disc_all_chars.prev_handle = start_handle - 1;
+ entry->disc_all_chars.end_handle = end_handle;
+ entry->disc_all_chars.cb = cb;
+ entry->disc_all_chars.cb_arg = cb_arg;
+
+ return 0;
+}
+
+/*****************************************************************************
+ * @read *
+ *****************************************************************************/
+
+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;
+}
+
+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_read_rsp(struct ble_hs_conn *conn, int status, void *value,
int value_len)
@@ -768,8 +819,8 @@ ble_gatt_rx_read_rsp(struct ble_hs_conn *conn, int status, void *value,
}
int
-ble_gatt_disc_all_services(uint16_t conn_handle, ble_gatt_disc_service_fn *cb,
- void *cb_arg)
+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;
@@ -778,72 +829,67 @@ ble_gatt_disc_all_services(uint16_t conn_handle, ble_gatt_disc_service_fn *cb,
if (rc != 0) {
return rc;
}
- entry->op = BLE_GATT_OP_DISC_ALL_SERVICES;
- entry->disc_all_services.prev_handle = 0x0000;
- entry->disc_all_services.cb = cb;
- entry->disc_all_services.cb_arg = cb_arg;
+ 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_disc_service_by_uuid(uint16_t conn_handle, void *service_uuid128,
- ble_gatt_disc_service_fn *cb, void *cb_arg)
+/*****************************************************************************
+ * @misc *
+ *****************************************************************************/
+
+void
+ble_gatt_wakeup(void)
{
+ const struct ble_gatt_dispatch_entry *dispatch;
struct ble_gatt_entry *entry;
+ struct ble_gatt_entry *prev;
+ struct ble_gatt_entry *next;
+ struct ble_gatt_entry *last;
int rc;
- rc = ble_gatt_new_entry(conn_handle, &entry);
- if (rc != 0) {
- return rc;
- }
- entry->op = BLE_GATT_OP_DISC_SERVICE_UUID;
- memcpy(entry->disc_service_uuid.service_uuid, service_uuid128, 16);
- entry->disc_service_uuid.prev_handle = 0x0000;
- entry->disc_service_uuid.cb = cb;
- entry->disc_service_uuid.cb_arg = cb_arg;
+ last = STAILQ_LAST(&ble_gatt_list, ble_gatt_entry, next);
- return 0;
-}
+ prev = NULL;
+ entry = STAILQ_FIRST(&ble_gatt_list);
+ while (prev != last) {
+ next = STAILQ_NEXT(entry, next);
-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)
-{
- struct ble_gatt_entry *entry;
- int rc;
+ if (entry->flags & BLE_GATT_ENTRY_F_PENDING) {
+ dispatch = ble_gatt_dispatch_get(entry->op);
+ rc = dispatch->kick_cb(entry);
+ if (rc == 0) {
+ ble_gatt_entry_set_expecting(entry, prev);
+ } else {
+ ble_gatt_entry_remove_free(entry, prev);
+ }
+ }
- rc = ble_gatt_new_entry(conn_handle, &entry);
- if (rc != 0) {
- return rc;
+ prev = entry;
+ entry = next;
}
- entry->op = BLE_GATT_OP_DISC_ALL_CHARS;
- entry->disc_all_chars.prev_handle = start_handle - 1;
- entry->disc_all_chars.end_handle = end_handle;
- entry->disc_all_chars.cb = cb;
- entry->disc_all_chars.cb_arg = cb_arg;
-
- return 0;
}
-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)
{
+ const struct ble_gatt_dispatch_entry *dispatch;
struct ble_gatt_entry *entry;
- int rc;
+ struct ble_gatt_entry *prev;
- rc = ble_gatt_new_entry(conn_handle, &entry);
- if (rc != 0) {
- return rc;
+ entry = ble_gatt_find(conn->bhc_handle, BLE_GATT_OP_NONE, 1, &prev);
+ if (entry == NULL) {
+ /* Not expecting a response from this device. */
+ return;
}
- entry->op = BLE_GATT_OP_READ;
- entry->read.handle = attr_handle;
- entry->read.cb = cb;
- entry->read.cb_arg = cb_arg;
- return 0;
+ dispatch = ble_gatt_dispatch_get(entry->op);
+ dispatch->rx_err_cb(entry, conn, rsp);
+
+ ble_gatt_entry_remove_free(entry, prev);
}
int