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/24 00:34:31 UTC
[2/6] incubator-mynewt-larva git commit: Separate gatt source into
gatt-client, gatt-server
Separate gatt source into gatt-client,gatt-server
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/2c857eba
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/2c857eba
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/2c857eba
Branch: refs/heads/master
Commit: 2c857eba2561329e5d146c9362a9722ddebd483a
Parents: 63761d7
Author: Christopher Collins <cc...@gmail.com>
Authored: Wed Dec 23 11:00:53 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Wed Dec 23 15:33:27 2015 -0800
----------------------------------------------------------------------
net/nimble/host/include/host/ble_gatt.h | 2 +-
net/nimble/host/src/ble_att_clt.c | 22 +-
net/nimble/host/src/ble_gap_conn.c | 2 +-
net/nimble/host/src/ble_gatt.c | 1285 +----------------
net/nimble/host/src/ble_gatt_priv.h | 56 +-
net/nimble/host/src/ble_gattc.c | 1320 ++++++++++++++++++
net/nimble/host/src/ble_hs.c | 4 +-
net/nimble/host/src/ble_hs_conn.c | 2 +-
net/nimble/host/src/test/ble_gatt_conn_test.c | 8 +-
net/nimble/host/src/test/ble_gatt_disc_c_test.c | 6 +-
net/nimble/host/src/test/ble_gatt_disc_s_test.c | 10 +-
net/nimble/host/src/test/ble_gatt_read_test.c | 8 +-
net/nimble/host/src/test/ble_gatt_write_test.c | 4 +-
13 files changed, 1415 insertions(+), 1314 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/2c857eba/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 04996e4..7b59d26 100644
--- a/net/nimble/host/include/host/ble_gatt.h
+++ b/net/nimble/host/include/host/ble_gatt.h
@@ -66,7 +66,7 @@ int ble_gatt_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle,
int ble_gatt_write(uint16_t conn_handle, uint16_t attr_handle, void *value,
uint16_t value_len, ble_gatt_attr_fn *cb, void *cb_arg);
-int ble_gatt_mtu(uint16_t conn_handle);
+int ble_gatt_exchange_mtu(uint16_t conn_handle);
int ble_gatt_init(void);
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/2c857eba/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 ad93428..5bf9ddf 100644
--- a/net/nimble/host/src/ble_att_clt.c
+++ b/net/nimble/host/src/ble_att_clt.c
@@ -84,7 +84,7 @@ ble_att_clt_rx_error(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
return rc;
}
- ble_gatt_rx_err(conn->bhc_handle, &rsp);
+ ble_gattc_rx_err(conn->bhc_handle, &rsp);
return 0;
}
@@ -141,7 +141,7 @@ ble_att_clt_rx_mtu(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
ble_att_set_peer_mtu(chan, rsp.bamc_mtu);
- ble_gatt_rx_mtu(conn, ble_l2cap_chan_mtu(chan));
+ ble_gattc_rx_mtu(conn, ble_l2cap_chan_mtu(chan));
return 0;
}
@@ -344,13 +344,13 @@ ble_att_clt_rx_read_type(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
goto done;
}
- ble_gatt_rx_read_type_adata(conn, &adata);
+ ble_gattc_rx_read_type_adata(conn, &adata);
os_mbuf_adj(*rxom, rsp.batp_length);
}
done:
/* Notify GATT that the response is done being parsed. */
- ble_gatt_rx_read_type_complete(conn, rc);
+ ble_gattc_rx_read_type_complete(conn, rc);
return 0;
@@ -420,7 +420,7 @@ ble_att_clt_rx_read(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
rc = 0;
done:
- ble_gatt_rx_read_rsp(conn, rc, value, value_len);
+ ble_gattc_rx_read_rsp(conn, rc, value, value_len);
return rc;
}
@@ -520,13 +520,13 @@ ble_att_clt_rx_read_group_type(struct ble_hs_conn *conn,
goto done;
}
- ble_gatt_rx_read_group_type_adata(conn, &adata);
+ ble_gattc_rx_read_group_type_adata(conn, &adata);
os_mbuf_adj(*rxom, rsp.bagp_length);
}
done:
/* Notify GATT that the response is done being parsed. */
- ble_gatt_rx_read_group_type_complete(conn, rc);
+ ble_gattc_rx_read_group_type_complete(conn, rc);
return 0;
}
@@ -616,12 +616,12 @@ ble_att_clt_rx_find_type_value(struct ble_hs_conn *conn,
break;
}
- ble_gatt_rx_find_type_value_hinfo(conn, &adata);
+ ble_gattc_rx_find_type_value_hinfo(conn, &adata);
os_mbuf_adj(*rxom, BLE_ATT_FIND_TYPE_VALUE_HINFO_BASE_SZ);
}
- /* Notify GATT that the full response has been parsed. */
- ble_gatt_rx_find_type_value_complete(conn, rc);
+ /* Notify GATT client that the full response has been parsed. */
+ ble_gattc_rx_find_type_value_complete(conn, rc);
return 0;
}
@@ -712,7 +712,7 @@ ble_att_clt_rx_write(struct ble_hs_conn *conn,
struct os_mbuf **rxom)
{
/* No payload. */
- ble_gatt_rx_write_rsp(conn);
+ ble_gattc_rx_write_rsp(conn);
return 0;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/2c857eba/net/nimble/host/src/ble_gap_conn.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap_conn.c b/net/nimble/host/src/ble_gap_conn.c
index 456411d..e853b5d 100644
--- a/net/nimble/host/src/ble_gap_conn.c
+++ b/net/nimble/host/src/ble_gap_conn.c
@@ -290,7 +290,7 @@ ble_gap_conn_rx_disconn_complete(struct hci_disconn_complete *evt)
ble_gap_conn_notify_terminate(evt->connection_handle, evt->status,
evt->reason);
- ble_gatt_connection_broken(evt->connection_handle);
+ ble_gattc_connection_broken(evt->connection_handle);
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/2c857eba/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 d092d6f..de2766a 100644
--- a/net/nimble/host/src/ble_gatt.c
+++ b/net/nimble/host/src/ble_gatt.c
@@ -1,894 +1,18 @@
-/**
- * Copyright (c) 2015 Runtime Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stddef.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include "os/os_mempool.h"
-#include "nimble/ble.h"
#include "ble_gatt_priv.h"
-#include "ble_hs_priv.h"
-#include "host/ble_hs_uuid.h"
-#include "ble_hs_conn.h"
-#include "ble_att_cmd.h"
-#include "ble_att_priv.h"
-
-struct ble_gatt_entry {
- STAILQ_ENTRY(ble_gatt_entry) next;
-
- uint8_t op;
- uint8_t flags;
- uint16_t conn_handle;
- union {
- struct {
- int (*cb)(int status, uint16_t conn_handle, uint16_t mtu,
- void *arg);
- void *cb_arg;
- } mtu;
-
- struct {
- uint16_t prev_handle;
- ble_gatt_disc_service_fn *cb;
- void *cb_arg;
- } disc_all_services;
-
- struct {
- uint8_t service_uuid[16];
- uint16_t prev_handle;
- ble_gatt_disc_service_fn *cb;
- void *cb_arg;
- } disc_service_uuid;
-
- struct {
- uint16_t prev_handle;
- uint16_t end_handle;
- ble_gatt_chr_fn *cb;
- void *cb_arg;
- } disc_all_chars;
-
- struct {
- uint16_t handle;
- ble_gatt_attr_fn *cb;
- void *cb_arg;
- } read;
-
- struct {
- struct ble_gatt_attr attr;
- ble_gatt_attr_fn *cb;
- void *cb_arg;
- } write;
- };
-};
-
-#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
-#define BLE_GATT_OP_DISC_SERVICE_UUID 2
-#define BLE_GATT_OP_DISC_ALL_CHARS 3
-#define BLE_GATT_OP_READ 4
-#define BLE_GATT_OP_WRITE_NO_RSP 5
-#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, int status);
-
-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_kick_write_no_rsp(struct ble_gatt_entry *entry);
-static int ble_gatt_kick_write(struct ble_gatt_entry *entry);
-
-static void ble_gatt_err_mtu(struct ble_gatt_entry *entry, int status);
-static void ble_gatt_err_disc_all_services(struct ble_gatt_entry *entry,
- int status);
-static void ble_gatt_err_disc_service_uuid(struct ble_gatt_entry *entry,
- int status);
-static void ble_gatt_err_disc_all_chars(struct ble_gatt_entry *entry,
- int status);
-static void ble_gatt_err_read(struct ble_gatt_entry *entry, int status);
-static void ble_gatt_err_write(struct ble_gatt_entry *entry, int status);
-
-struct ble_gatt_dispatch_entry {
- ble_gatt_kick_fn *kick_cb;
- ble_gatt_err_fn *err_cb;
-};
-
-static const struct ble_gatt_dispatch_entry
- ble_gatt_dispatch[BLE_GATT_OP_MAX] = {
-
- [BLE_GATT_OP_MTU] = {
- .kick_cb = ble_gatt_kick_mtu,
- .err_cb = ble_gatt_err_mtu,
- },
- [BLE_GATT_OP_DISC_ALL_SERVICES] = {
- .kick_cb = ble_gatt_kick_disc_all_services,
- .err_cb = ble_gatt_err_disc_all_services,
- },
- [BLE_GATT_OP_DISC_SERVICE_UUID] = {
- .kick_cb = ble_gatt_kick_disc_service_uuid,
- .err_cb = ble_gatt_err_disc_service_uuid,
- },
- [BLE_GATT_OP_DISC_ALL_CHARS] = {
- .kick_cb = ble_gatt_kick_disc_all_chars,
- .err_cb = ble_gatt_err_disc_all_chars,
- },
- [BLE_GATT_OP_READ] = {
- .kick_cb = ble_gatt_kick_read,
- .err_cb = ble_gatt_err_read,
- },
- [BLE_GATT_OP_WRITE_NO_RSP] = {
- .kick_cb = ble_gatt_kick_write_no_rsp,
- .err_cb = NULL,
- },
- [BLE_GATT_OP_WRITE] = {
- .kick_cb = ble_gatt_kick_write,
- .err_cb = ble_gatt_err_write,
- },
-};
-
-#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;
-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)
-{
- assert(op < BLE_GATT_OP_MAX);
- return ble_gatt_dispatch + op;
-}
-
-static struct ble_gatt_entry *
-ble_gatt_entry_alloc(void)
-{
- struct ble_gatt_entry *entry;
-
- entry = os_memblock_get(&ble_gatt_entry_pool);
- if (entry != NULL) {
- memset(entry, 0, sizeof *entry);
- }
-
- return entry;
-}
-
-static void
-ble_gatt_entry_free(struct ble_gatt_entry *entry)
-{
- int rc;
-
- rc = os_memblock_put(&ble_gatt_entry_pool, entry);
- assert(rc == 0);
-}
-
-static void
-ble_gatt_entry_remove(struct ble_gatt_entry *entry,
- struct ble_gatt_entry *prev)
-{
- if (prev == NULL) {
- assert(STAILQ_FIRST(&ble_gatt_list) == entry);
- STAILQ_REMOVE_HEAD(&ble_gatt_list, next);
- } else {
- assert(STAILQ_NEXT(prev, next) == entry);
- STAILQ_NEXT(prev, next) = STAILQ_NEXT(entry, next);
- }
-}
-
-static void
-ble_gatt_entry_remove_free(struct ble_gatt_entry *entry,
- struct ble_gatt_entry *prev)
-{
- ble_gatt_entry_remove(entry, prev);
- ble_gatt_entry_free(entry);
-}
-
-static int
-ble_gatt_entry_matches(struct ble_gatt_entry *entry, uint16_t conn_handle,
- uint8_t att_op, int expecting_only)
-{
- if (conn_handle != entry->conn_handle) {
- return 0;
- }
-
- if (att_op != entry->op && att_op != BLE_GATT_OP_NONE) {
- return 0;
- }
-
- if (expecting_only &&
- !(entry->flags & BLE_GATT_ENTRY_F_EXPECTING)) {
-
- return 0;
- }
-
- return 1;
-}
-
-static struct ble_gatt_entry *
-ble_gatt_find(uint16_t conn_handle, uint8_t att_op, int expecting_only,
- struct ble_gatt_entry **out_prev)
-{
- struct ble_gatt_entry *entry;
- struct ble_gatt_entry *prev;
-
- prev = NULL;
- STAILQ_FOREACH(entry, &ble_gatt_list, next) {
- if (ble_gatt_entry_matches(entry, conn_handle, att_op,
- expecting_only)) {
- if (out_prev != NULL) {
- *out_prev = prev;
- }
- return entry;
- }
-
- prev = entry;
- }
-
- return NULL;
-}
-
-static void
-ble_gatt_entry_set_pending(struct ble_gatt_entry *entry)
-{
- assert(!(entry->flags & BLE_GATT_ENTRY_F_PENDING));
-
- entry->flags &= ~BLE_GATT_ENTRY_F_EXPECTING;
- entry->flags |= BLE_GATT_ENTRY_F_PENDING;
- ble_hs_kick_gatt();
-}
-
-static void
-ble_gatt_entry_set_expecting(struct ble_gatt_entry *entry,
- struct ble_gatt_entry *prev)
-{
- assert(!(entry->flags & BLE_GATT_ENTRY_F_EXPECTING));
-
- ble_gatt_entry_remove(entry, prev);
- entry->flags &= ~BLE_GATT_ENTRY_F_PENDING;
- entry->flags |= BLE_GATT_ENTRY_F_EXPECTING;
- STAILQ_INSERT_TAIL(&ble_gatt_list, entry, next);
-}
-
-static int
-ble_gatt_new_entry(uint16_t conn_handle, uint8_t op,
- struct ble_gatt_entry **entry)
-{
- struct ble_hs_conn *conn;
-
- *entry = NULL;
-
- /* Ensure we have a connection with the specified handle. */
- conn = ble_hs_conn_find(conn_handle);
- if (conn == NULL) {
- return BLE_HS_ENOTCONN;
- }
-
- *entry = ble_gatt_entry_alloc();
- if (*entry == NULL) {
- return BLE_HS_ENOMEM;
- }
-
- memset(*entry, 0, sizeof **entry);
- (*entry)->op = op;
- (*entry)->conn_handle = conn_handle;
-
- STAILQ_INSERT_TAIL(&ble_gatt_list, *entry, next);
-
- ble_gatt_entry_set_pending(*entry);
-
- 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 *
- *****************************************************************************/
-
-static int
-ble_gatt_mtu_cb(struct ble_gatt_entry *entry, int status, uint16_t mtu)
-{
- int rc;
-
- if (entry->mtu.cb == NULL) {
- rc = 0;
- } else {
- rc = entry->mtu.cb(entry->conn_handle, status, mtu, entry->mtu.cb_arg);
- }
-
- return rc;
-}
-
-static int
-ble_gatt_kick_mtu(struct ble_gatt_entry *entry)
-{
- struct ble_att_mtu_cmd req;
- struct ble_l2cap_chan *chan;
- struct ble_hs_conn *conn;
- int rc;
-
- conn = ble_hs_conn_find(entry->conn_handle);
- if (conn == NULL) {
- rc = BLE_HS_ENOTCONN;
- goto err;
- }
-
- chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
- assert(chan != NULL);
-
- req.bamc_mtu = chan->blc_my_mtu;
- rc = ble_att_clt_tx_mtu(conn, &req);
- if (rc != 0) {
- goto err;
- }
-
- return 0;
-
-err:
- if (ble_gatt_tx_postpone_chk(entry, rc)) {
- return BLE_HS_EAGAIN;
- }
-
- ble_gatt_mtu_cb(entry, rc, 0);
- return rc;
-}
-
-static void
-ble_gatt_err_mtu(struct ble_gatt_entry *entry, int status)
-{
- ble_gatt_mtu_cb(entry, status, 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;
- }
-
- ble_gatt_mtu_cb(entry, 0, chan_mtu);
- 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, BLE_GATT_OP_MTU, &entry);
- if (rc != 0) {
- return rc;
- }
-
- return 0;
-}
-
-/*****************************************************************************
- * @discover all services *
- *****************************************************************************/
-
-static int
-ble_gatt_disc_all_services_cb(struct ble_gatt_entry *entry,
- int status, struct ble_gatt_service *service)
-{
- int 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 rc;
-}
-
-static int
-ble_gatt_kick_disc_all_services(struct ble_gatt_entry *entry)
-{
- 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) {
- rc = BLE_HS_ENOTCONN;
- goto err;
- }
-
- 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) {
- goto err;
- }
-
- return 0;
-
-err:
- if (ble_gatt_tx_postpone_chk(entry, rc)) {
- return BLE_HS_EAGAIN;
- }
-
- ble_gatt_disc_all_services_cb(entry, rc, NULL);
- return rc;
-}
-
-static void
-ble_gatt_err_disc_all_services(struct ble_gatt_entry *entry, int status)
-{
- if (status == BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_FOUND)) {
- /* Discovery is complete. */
- status = 0;
- }
-
- ble_gatt_disc_all_services_cb(entry, status, NULL);
-}
-
-void
-ble_gatt_rx_read_group_type_adata(struct ble_hs_conn *conn,
- struct ble_att_clt_adata *adata)
-{
- struct ble_gatt_service service;
- struct ble_gatt_entry *entry;
- struct ble_gatt_entry *prev;
- uint16_t uuid16;
- int cbrc;
- int rc;
-
- entry = ble_gatt_find(conn->bhc_handle, BLE_GATT_OP_DISC_ALL_SERVICES, 1,
- &prev);
- if (entry == NULL) {
- /* Not expecting a response from this device. */
- return;
- }
-
- switch (adata->value_len) {
- case 2:
- uuid16 = le16toh(adata->value);
- rc = ble_hs_uuid_from_16bit(uuid16, service.uuid128);
- if (rc != 0) {
- goto done;
- }
- break;
-
- case 16:
- memcpy(service.uuid128, adata->value, 16);
- break;
-
- default:
- rc = BLE_HS_EMSGSIZE;
- goto done;
- }
-
- entry->disc_all_services.prev_handle = adata->end_group_handle;
-
- service.start_handle = adata->att_handle;
- service.end_handle = adata->end_group_handle;
-
- rc = 0;
-
-done:
- cbrc = ble_gatt_disc_all_services_cb(entry, rc, &service);
- if (rc != 0 || cbrc != 0) {
- ble_gatt_entry_remove_free(entry, prev);
- }
-}
-
-void
-ble_gatt_rx_read_group_type_complete(struct ble_hs_conn *conn, int rc)
-{
- struct ble_gatt_entry *entry;
- struct ble_gatt_entry *prev;
-
- entry = ble_gatt_find(conn->bhc_handle, BLE_GATT_OP_DISC_ALL_SERVICES, 1,
- &prev);
- if (entry == NULL) {
- /* Not expecting a response from this device. */
- return;
- }
-
- if (rc != 0 || entry->disc_all_services.prev_handle == 0xffff) {
- /* Error or all services discovered. */
- ble_gatt_disc_all_services_cb(entry, rc, NULL);
- ble_gatt_entry_remove_free(entry, prev);
- } else {
- /* Send follow-up request. */
- ble_gatt_entry_set_pending(entry);
- }
-}
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, BLE_GATT_OP_DISC_ALL_SERVICES,
- &entry);
- if (rc != 0) {
- return rc;
- }
- 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_disc_service_uuid_cb(struct ble_gatt_entry *entry, int status,
- struct ble_gatt_service *service)
-{
- int rc;
-
- if (entry->disc_service_uuid.cb == NULL) {
- rc = 0;
- } else {
- rc = entry->disc_service_uuid.cb(entry->conn_handle, status, service,
- entry->disc_service_uuid.cb_arg);
- }
-
- return rc;
-}
-
-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) {
- rc = BLE_HS_ENOTCONN;
- goto err;
- }
-
- 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) {
- goto err;
- }
-
- return 0;
-
-err:
- if (ble_gatt_tx_postpone_chk(entry, rc)) {
- return BLE_HS_EAGAIN;
- }
-
- ble_gatt_disc_service_uuid_cb(entry, rc, NULL);
- return rc;
-}
-
-static void
-ble_gatt_err_disc_service_uuid(struct ble_gatt_entry *entry, int status)
-{
- if (status == BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_FOUND)) {
- /* Discovery is complete. */
- status = 0;
- }
-
- ble_gatt_disc_service_uuid_cb(entry, status, NULL);
-}
-
-void
-ble_gatt_rx_find_type_value_hinfo(struct ble_hs_conn *conn,
- struct ble_att_clt_adata *adata)
-{
- struct ble_gatt_service service;
- struct ble_gatt_entry *entry;
- struct ble_gatt_entry *prev;
- int rc;
-
- entry = ble_gatt_find(conn->bhc_handle, BLE_GATT_OP_DISC_SERVICE_UUID, 1,
- &prev);
- if (entry == NULL) {
- /* Not expecting a response from this device. */
- return;
- }
-
- entry->disc_service_uuid.prev_handle = adata->end_group_handle;
-
- service.start_handle = adata->att_handle;
- service.end_handle = adata->end_group_handle;
- memcpy(service.uuid128, entry->disc_service_uuid.service_uuid, 16);
-
- rc = ble_gatt_disc_service_uuid_cb(entry, 0, &service);
- if (rc != 0) {
- ble_gatt_entry_remove_free(entry, prev);
- }
-}
-
-void
-ble_gatt_rx_find_type_value_complete(struct ble_hs_conn *conn, int rc)
-{
- struct ble_gatt_entry *entry;
- struct ble_gatt_entry *prev;
-
- entry = ble_gatt_find(conn->bhc_handle, BLE_GATT_OP_DISC_SERVICE_UUID, 1,
- &prev);
- if (entry == NULL) {
- /* Not expecting a response from this device. */
- return;
- }
-
- if (rc != 0 || entry->disc_service_uuid.prev_handle == 0xffff) {
- /* Error or all services discovered. */
- ble_gatt_disc_service_uuid_cb(entry, rc, NULL);
- ble_gatt_entry_remove_free(entry, prev);
- } else {
- /* Send follow-up request. */
- ble_gatt_entry_set_pending(entry);
- }
+ return ble_gattc_disc_all_services(conn_handle, cb, cb_arg);
}
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, BLE_GATT_OP_DISC_SERVICE_UUID,
- &entry);
- if (rc != 0) {
- return rc;
- }
- 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_disc_all_chars_cb(struct ble_gatt_entry *entry, int status,
- struct ble_gatt_chr *chr)
-{
- int rc;
-
- if (entry->disc_all_chars.cb == NULL) {
- rc = 0;
- } else {
- rc = entry->disc_all_chars.cb(entry->conn_handle, status, chr,
- entry->disc_all_chars.cb_arg);
- }
-
- return rc;
-}
-
-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) {
- rc = BLE_HS_ENOTCONN;
- goto err;
- }
-
- 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) {
- goto err;
- }
-
- return 0;
-
-err:
- if (ble_gatt_tx_postpone_chk(entry, rc)) {
- return BLE_HS_EAGAIN;
- }
-
- ble_gatt_disc_all_chars_cb(entry, rc, NULL);
- return rc;
-}
-
-static void
-ble_gatt_err_disc_all_chars(struct ble_gatt_entry *entry, int status)
-{
- if (status == BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_FOUND)) {
- /* Discovery is complete. */
- status = 0;
- }
-
- ble_gatt_disc_all_chars_cb(entry, status, NULL);
-}
-
-void
-ble_gatt_rx_read_type_adata(struct ble_hs_conn *conn,
- struct ble_att_clt_adata *adata)
-{
- struct ble_gatt_entry *entry;
- struct ble_gatt_entry *prev;
- struct ble_gatt_chr chr;
- uint16_t uuid16;
- int cbrc;
- int rc;
-
- entry = ble_gatt_find(conn->bhc_handle, BLE_GATT_OP_DISC_ALL_CHARS, 1,
- &prev);
- if (entry == NULL) {
- /* Not expecting a response from this device. */
- return;
- }
-
- memset(&chr, 0, sizeof chr);
- chr.decl_handle = adata->att_handle;
-
- switch (adata->value_len) {
- case BLE_GATT_CHR_DECL_SZ_16:
- uuid16 = le16toh(adata->value + 3);
- rc = ble_hs_uuid_from_16bit(uuid16, chr.uuid128);
- if (rc != 0) {
- rc = BLE_HS_EBADDATA;
- goto done;
- }
- break;
-
- case BLE_GATT_CHR_DECL_SZ_128:
- memcpy(chr.uuid128, adata->value + 3, 16);
- break;
-
- default:
- rc = BLE_HS_EBADDATA;
- goto done;
- }
-
- entry->disc_all_chars.prev_handle = adata->att_handle;
-
- chr.properties = adata->value[0];
- chr.value_handle = le16toh(adata->value + 1);
-
- rc = 0;
-
-done:
- cbrc = ble_gatt_disc_all_chars_cb(entry, rc, &chr);
- if (rc != 0 || cbrc != 0) {
- ble_gatt_entry_remove_free(entry, prev);
- }
-}
-
-void
-ble_gatt_rx_read_type_complete(struct ble_hs_conn *conn, int rc)
-{
- struct ble_gatt_entry *entry;
- struct ble_gatt_entry *prev;
-
- entry = ble_gatt_find(conn->bhc_handle, BLE_GATT_OP_DISC_ALL_CHARS, 1,
- &prev);
- if (entry == NULL) {
- /* Not expecting a response from this device. */
- return;
- }
-
- if (rc != 0 || entry->disc_all_chars.prev_handle ==
- entry->disc_all_chars.end_handle) {
- /* Error or all services discovered. */
- ble_gatt_disc_all_chars_cb(entry, rc, NULL);
- ble_gatt_entry_remove_free(entry, prev);
- } else {
- /* Send follow-up request. */
- ble_gatt_entry_set_pending(entry);
- }
+ return ble_gattc_disc_service_by_uuid(conn_handle, service_uuid128, cb,
+ cb_arg);
}
int
@@ -896,389 +20,45 @@ ble_gatt_disc_all_chars(uint16_t conn_handle, uint16_t start_handle,
uint16_t end_handle, ble_gatt_chr_fn *cb,
void *cb_arg)
{
- struct ble_gatt_entry *entry;
- int rc;
-
- rc = ble_gatt_new_entry(conn_handle, BLE_GATT_OP_DISC_ALL_CHARS, &entry);
- if (rc != 0) {
- return rc;
- }
- 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_read_cb(struct ble_gatt_entry *entry, int status,
- struct ble_gatt_attr *attr)
-{
- int rc;
-
- if (entry->read.cb == NULL) {
- rc = 0;
- } else {
- rc = entry->read.cb(entry->conn_handle, status, attr,
- entry->read.cb_arg);
- }
-
- return rc;
-}
-
-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) {
- rc = BLE_HS_ENOTCONN;
- goto err;
- }
-
- req.barq_handle = entry->read.handle;
- rc = ble_att_clt_tx_read(conn, &req);
- if (rc != 0) {
- goto err;
- }
-
- return 0;
-
-err:
- if (ble_gatt_tx_postpone_chk(entry, rc)) {
- return BLE_HS_EAGAIN;
- }
-
- ble_gatt_read_cb(entry, rc, NULL);
- return rc;
-}
-
-static void
-ble_gatt_err_read(struct ble_gatt_entry *entry, int status)
-{
- ble_gatt_read_cb(entry, status, NULL);
-}
-
-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;
-
- ble_gatt_read_cb(entry, status, &attr);
-
- /* The read operation only has a single request / response exchange. */
- ble_gatt_entry_remove_free(entry, prev);
+ return ble_gattc_disc_all_chars(conn_handle, start_handle, end_handle, cb,
+ cb_arg);
}
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, BLE_GATT_OP_READ, &entry);
- if (rc != 0) {
- return rc;
- }
- entry->read.handle = attr_handle;
- entry->read.cb = cb;
- entry->read.cb_arg = cb_arg;
-
- return 0;
-}
-
-/*****************************************************************************
- * @write no response *
- *****************************************************************************/
-
-static int
-ble_gatt_write_cb(struct ble_gatt_entry *entry, int status)
-{
- int rc;
-
- if (entry->write.cb == NULL) {
- rc = 0;
- } else {
- rc = entry->write.cb(entry->conn_handle, status, &entry->write.attr,
- entry->write.cb_arg);
- }
-
- return rc;
-}
-
-static int
-ble_gatt_kick_write_no_rsp(struct ble_gatt_entry *entry)
-{
- struct ble_att_write_req req;
- struct ble_hs_conn *conn;
- int rc;
-
- conn = ble_hs_conn_find(entry->conn_handle);
- if (conn == NULL) {
- rc = BLE_HS_ENOTCONN;
- goto err;
- }
-
- req.bawq_handle = entry->write.attr.handle;
- rc = ble_att_clt_tx_write_cmd(conn, &req, entry->write.attr.value,
- entry->write.attr.value_len);
- if (rc != 0) {
- goto err;
- }
-
- /* No response expected; call callback immediately and return nonzero to
- * indicate the entry should be freed.
- */
- ble_gatt_write_cb(entry, 0);
-
- return 1;
-
-err:
- if (ble_gatt_tx_postpone_chk(entry, rc)) {
- return BLE_HS_EAGAIN;
- }
-
- ble_gatt_write_cb(entry, rc);
- return rc;
+ return ble_gattc_read(conn_handle, attr_handle, cb, cb_arg);
}
int
-ble_gatt_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle, void *value,
- uint16_t value_len, ble_gatt_attr_fn *cb, void *cb_arg)
+ble_gatt_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle,
+ void *value, uint16_t value_len,
+ ble_gatt_attr_fn *cb, void *cb_arg)
{
- struct ble_gatt_entry *entry;
- int rc;
-
- rc = ble_gatt_new_entry(conn_handle, BLE_GATT_OP_WRITE_NO_RSP, &entry);
- if (rc != 0) {
- return rc;
- }
-
- entry->write.attr.handle = attr_handle;
- entry->write.attr.value = value;
- entry->write.attr.value_len = value_len;
- entry->write.cb = cb;
- entry->write.cb_arg = cb_arg;
-
- return 0;
-}
-
-/*****************************************************************************
- * @write *
- *****************************************************************************/
-
-static int
-ble_gatt_kick_write(struct ble_gatt_entry *entry)
-{
- struct ble_att_write_req req;
- struct ble_hs_conn *conn;
- int rc;
-
- conn = ble_hs_conn_find(entry->conn_handle);
- if (conn == NULL) {
- rc = BLE_HS_ENOTCONN;
- goto err;
- }
-
- req.bawq_handle = entry->write.attr.handle;
- rc = ble_att_clt_tx_write_req(conn, &req, entry->write.attr.value,
- entry->write.attr.value_len);
- if (rc != 0) {
- goto err;
- }
-
- return 0;
-
-err:
- if (ble_gatt_tx_postpone_chk(entry, rc)) {
- return BLE_HS_EAGAIN;
- }
-
- ble_gatt_write_cb(entry, rc);
- return rc;
-}
-
-static void
-ble_gatt_err_write(struct ble_gatt_entry *entry, int status)
-{
- ble_gatt_write_cb(entry, status);
-}
-
-void
-ble_gatt_rx_write_rsp(struct ble_hs_conn *conn)
-{
- struct ble_gatt_entry *entry;
- struct ble_gatt_entry *prev;
-
- entry = ble_gatt_find(conn->bhc_handle, BLE_GATT_OP_WRITE, 1, &prev);
- if (entry == NULL) {
- /* Not expecting a response from this device. */
- return;
- }
-
- ble_gatt_write_cb(entry, 0);
-
- /* The write operation only has a single request / response exchange. */
- ble_gatt_entry_remove_free(entry, prev);
+ return ble_gattc_write_no_rsp(conn_handle, attr_handle, value, value_len,
+ cb, cb_arg);
}
int
ble_gatt_write(uint16_t conn_handle, uint16_t attr_handle, void *value,
uint16_t value_len, ble_gatt_attr_fn *cb, void *cb_arg)
{
- struct ble_gatt_entry *entry;
- int rc;
-
- rc = ble_gatt_new_entry(conn_handle, BLE_GATT_OP_WRITE, &entry);
- if (rc != 0) {
- return rc;
- }
-
- entry->write.attr.handle = attr_handle;
- entry->write.attr.value = value;
- entry->write.attr.value_len = value_len;
- entry->write.cb = cb;
- entry->write.cb_arg = cb_arg;
-
- return 0;
+ return ble_gattc_write(conn_handle, attr_handle, value, value_len, cb,
+ 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;
- int rc;
-
- prev = NULL;
- entry = STAILQ_FIRST(&ble_gatt_list);
- while (entry != NULL) {
- 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);
- 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. */
- break;
-
- case BLE_HS_EAGAIN:
- /* Transmit failed due to resource shortage. Reschedule. */
- entry->flags &= ~BLE_GATT_ENTRY_F_PENDING;
- /* Current entry remains; reseat prev. */
- prev = entry;
- break;
-
- default:
- /* Transmit failed. Abort procedure. */
- ble_gatt_entry_remove_free(entry, prev);
- /* Current entry removed; old prev still valid. */
- break;
- }
- } else {
- prev = entry;
- }
-
- entry = next;
- }
-}
-
-void
-ble_gatt_rx_err(uint16_t conn_handle, struct ble_att_error_rsp *rsp)
+int
+ble_gatt_exchange_mtu(uint16_t conn_handle)
{
- const struct ble_gatt_dispatch_entry *dispatch;
- struct ble_gatt_entry *entry;
- struct ble_gatt_entry *prev;
-
- entry = ble_gatt_find(conn_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);
- if (dispatch->err_cb != NULL) {
- dispatch->err_cb(entry, BLE_HS_ERR_ATT_BASE + rsp->baep_error_code);
- }
-
- ble_gatt_entry_remove_free(entry, prev);
+ return ble_gattc_exchange_mtu(conn_handle);
}
-/**
- * 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)
{
- const struct ble_gatt_dispatch_entry *dispatch;
- struct ble_gatt_entry *entry;
- struct ble_gatt_entry *prev;
-
- while (1) {
- entry = ble_gatt_find(conn_handle, BLE_GATT_OP_NONE, 0, &prev);
- if (entry == NULL) {
- break;
- }
-
- dispatch = ble_gatt_dispatch_get(entry->op);
- dispatch->err_cb(entry, BLE_HS_ENOTCONN);
-
- ble_gatt_entry_remove_free(entry, prev);
- }
-}
-
-/**
- * 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);
- }
- }
- }
+ ble_gattc_connection_broken(conn_handle);
+ /* XXX: Notify GATT server. */
}
int
@@ -1286,35 +66,12 @@ ble_gatt_init(void)
{
int rc;
- free(ble_gatt_entry_mem);
-
- ble_gatt_entry_mem = malloc(
- OS_MEMPOOL_BYTES(BLE_GATT_NUM_ENTRIES,
- sizeof (struct ble_gatt_entry)));
- if (ble_gatt_entry_mem == NULL) {
- rc = BLE_HS_ENOMEM;
- goto err;
- }
-
- rc = os_mempool_init(&ble_gatt_entry_pool,
- BLE_GATT_NUM_ENTRIES,
- sizeof (struct ble_gatt_entry),
- ble_gatt_entry_mem,
- "ble_gatt_entry_pool");
+ rc = ble_gattc_init();
if (rc != 0) {
- goto err;
+ return rc;
}
- STAILQ_INIT(&ble_gatt_list);
-
- os_callout_func_init(&ble_gatt_retx_timer, &ble_hs_evq,
- ble_gatt_retx_timer_exp, NULL);
+ /* XXX: Init server. */
return 0;
-
-err:
- free(ble_gatt_entry_mem);
- ble_gatt_entry_mem = NULL;
-
- return rc;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/2c857eba/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 6eb1dfd..8a7e850 100644
--- a/net/nimble/host/src/ble_gatt_priv.h
+++ b/net/nimble/host/src/ble_gatt_priv.h
@@ -22,22 +22,46 @@
#define BLE_GATT_CHR_DECL_SZ_16 5
#define BLE_GATT_CHR_DECL_SZ_128 19
-void ble_gatt_rx_err(uint16_t conn_handle, struct ble_att_error_rsp *rsp);
-void ble_gatt_wakeup(void);
-void ble_gatt_rx_mtu(struct ble_hs_conn *conn, uint16_t chan_mtu);
-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);
-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);
+/*** @gen */
void ble_gatt_connection_broken(uint16_t conn_handle);
+/*** @client */
+int ble_gattc_disc_all_services(uint16_t conn_handle,
+ ble_gatt_disc_service_fn *cb,
+ void *cb_arg);
+int ble_gattc_disc_service_by_uuid(uint16_t conn_handle, void *service_uuid128,
+ ble_gatt_disc_service_fn *cb, void *cb_arg);
+int ble_gattc_disc_all_chars(uint16_t conn_handle, uint16_t start_handle,
+ uint16_t end_handle, ble_gatt_chr_fn *cb,
+ void *cb_arg);
+int ble_gattc_read(uint16_t conn_handle, uint16_t attr_handle,
+ ble_gatt_attr_fn *cb, void *cb_arg);
+int ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle,
+ void *value, uint16_t value_len,
+ ble_gatt_attr_fn *cb, void *cb_arg);
+int ble_gattc_write(uint16_t conn_handle, uint16_t attr_handle, void *value,
+ uint16_t value_len, ble_gatt_attr_fn *cb, void *cb_arg);
+
+int ble_gattc_exchange_mtu(uint16_t conn_handle);
+
+void ble_gattc_rx_err(uint16_t conn_handle, struct ble_att_error_rsp *rsp);
+void ble_gattc_wakeup(void);
+void ble_gattc_rx_mtu(struct ble_hs_conn *conn, uint16_t chan_mtu);
+void ble_gattc_rx_read_type_adata(struct ble_hs_conn *conn,
+ struct ble_att_clt_adata *adata);
+void ble_gattc_rx_read_type_complete(struct ble_hs_conn *conn, int rc);
+void ble_gattc_rx_read_rsp(struct ble_hs_conn *conn, int status, void *value,
+ int value_len);
+void ble_gattc_rx_read_group_type_adata(struct ble_hs_conn *conn,
+ struct ble_att_clt_adata *adata);
+void ble_gattc_rx_read_group_type_complete(struct ble_hs_conn *conn, int rc);
+void ble_gattc_rx_find_type_value_hinfo(struct ble_hs_conn *conn,
+ struct ble_att_clt_adata *adata);
+void ble_gattc_rx_find_type_value_complete(struct ble_hs_conn *conn, int rc);
+void ble_gattc_rx_write_rsp(struct ble_hs_conn *conn);
+void ble_gattc_connection_txable(uint16_t conn_handle);
+void ble_gattc_connection_broken(uint16_t conn_handle);
+
+int ble_gattc_init(void);
+
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/2c857eba/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
new file mode 100644
index 0000000..bd48e41
--- /dev/null
+++ b/net/nimble/host/src/ble_gattc.c
@@ -0,0 +1,1320 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stddef.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include "os/os_mempool.h"
+#include "nimble/ble.h"
+#include "ble_gatt_priv.h"
+#include "ble_hs_priv.h"
+#include "host/ble_hs_uuid.h"
+#include "ble_hs_conn.h"
+#include "ble_att_cmd.h"
+#include "ble_att_priv.h"
+
+struct ble_gattc_entry {
+ STAILQ_ENTRY(ble_gattc_entry) next;
+
+ uint8_t op;
+ uint8_t flags;
+ uint16_t conn_handle;
+ union {
+ struct {
+ int (*cb)(int status, uint16_t conn_handle, uint16_t mtu,
+ void *arg);
+ void *cb_arg;
+ } mtu;
+
+ struct {
+ uint16_t prev_handle;
+ ble_gatt_disc_service_fn *cb;
+ void *cb_arg;
+ } disc_all_services;
+
+ struct {
+ uint8_t service_uuid[16];
+ uint16_t prev_handle;
+ ble_gatt_disc_service_fn *cb;
+ void *cb_arg;
+ } disc_service_uuid;
+
+ struct {
+ uint16_t prev_handle;
+ uint16_t end_handle;
+ ble_gatt_chr_fn *cb;
+ void *cb_arg;
+ } disc_all_chars;
+
+ struct {
+ uint16_t handle;
+ ble_gatt_attr_fn *cb;
+ void *cb_arg;
+ } read;
+
+ struct {
+ struct ble_gatt_attr attr;
+ ble_gatt_attr_fn *cb;
+ void *cb_arg;
+ } write;
+ };
+};
+
+#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
+#define BLE_GATT_OP_DISC_SERVICE_UUID 2
+#define BLE_GATT_OP_DISC_ALL_CHARS 3
+#define BLE_GATT_OP_READ 4
+#define BLE_GATT_OP_WRITE_NO_RSP 5
+#define BLE_GATT_OP_WRITE 6
+#define BLE_GATT_OP_MAX 7
+
+static struct os_callout_func ble_gattc_retx_timer;
+
+typedef int ble_gattc_kick_fn(struct ble_gattc_entry *entry);
+typedef void ble_gattc_err_fn(struct ble_gattc_entry *entry, int status);
+
+static int ble_gattc_kick_mtu(struct ble_gattc_entry *entry);
+static int ble_gattc_kick_disc_all_services(struct ble_gattc_entry *entry);
+static int ble_gattc_kick_disc_service_uuid(struct ble_gattc_entry *entry);
+static int ble_gattc_kick_disc_all_chars(struct ble_gattc_entry *entry);
+static int ble_gattc_kick_read(struct ble_gattc_entry *entry);
+static int ble_gattc_kick_write_no_rsp(struct ble_gattc_entry *entry);
+static int ble_gattc_kick_write(struct ble_gattc_entry *entry);
+
+static void ble_gattc_err_mtu(struct ble_gattc_entry *entry, int status);
+static void ble_gattc_err_disc_all_services(struct ble_gattc_entry *entry,
+ int status);
+static void ble_gattc_err_disc_service_uuid(struct ble_gattc_entry *entry,
+ int status);
+static void ble_gattc_err_disc_all_chars(struct ble_gattc_entry *entry,
+ int status);
+static void ble_gattc_err_read(struct ble_gattc_entry *entry, int status);
+static void ble_gattc_err_write(struct ble_gattc_entry *entry, int status);
+
+struct ble_gattc_dispatch_entry {
+ ble_gattc_kick_fn *kick_cb;
+ ble_gattc_err_fn *err_cb;
+};
+
+static const struct ble_gattc_dispatch_entry
+ ble_gattc_dispatch[BLE_GATT_OP_MAX] = {
+
+ [BLE_GATT_OP_MTU] = {
+ .kick_cb = ble_gattc_kick_mtu,
+ .err_cb = ble_gattc_err_mtu,
+ },
+ [BLE_GATT_OP_DISC_ALL_SERVICES] = {
+ .kick_cb = ble_gattc_kick_disc_all_services,
+ .err_cb = ble_gattc_err_disc_all_services,
+ },
+ [BLE_GATT_OP_DISC_SERVICE_UUID] = {
+ .kick_cb = ble_gattc_kick_disc_service_uuid,
+ .err_cb = ble_gattc_err_disc_service_uuid,
+ },
+ [BLE_GATT_OP_DISC_ALL_CHARS] = {
+ .kick_cb = ble_gattc_kick_disc_all_chars,
+ .err_cb = ble_gattc_err_disc_all_chars,
+ },
+ [BLE_GATT_OP_READ] = {
+ .kick_cb = ble_gattc_kick_read,
+ .err_cb = ble_gattc_err_read,
+ },
+ [BLE_GATT_OP_WRITE_NO_RSP] = {
+ .kick_cb = ble_gattc_kick_write_no_rsp,
+ .err_cb = NULL,
+ },
+ [BLE_GATT_OP_WRITE] = {
+ .kick_cb = ble_gattc_kick_write,
+ .err_cb = ble_gattc_err_write,
+ },
+};
+
+#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_gattc_entry_mem;
+static struct os_mempool ble_gattc_entry_pool;
+
+static STAILQ_HEAD(, ble_gattc_entry) ble_gattc_list;
+
+/*****************************************************************************
+ * @entry *
+ *****************************************************************************/
+
+static const struct ble_gattc_dispatch_entry *
+ble_gattc_dispatch_get(uint8_t op)
+{
+ assert(op < BLE_GATT_OP_MAX);
+ return ble_gattc_dispatch + op;
+}
+
+static struct ble_gattc_entry *
+ble_gattc_entry_alloc(void)
+{
+ struct ble_gattc_entry *entry;
+
+ entry = os_memblock_get(&ble_gattc_entry_pool);
+ if (entry != NULL) {
+ memset(entry, 0, sizeof *entry);
+ }
+
+ return entry;
+}
+
+static void
+ble_gattc_entry_free(struct ble_gattc_entry *entry)
+{
+ int rc;
+
+ rc = os_memblock_put(&ble_gattc_entry_pool, entry);
+ assert(rc == 0);
+}
+
+static void
+ble_gattc_entry_remove(struct ble_gattc_entry *entry,
+ struct ble_gattc_entry *prev)
+{
+ if (prev == NULL) {
+ assert(STAILQ_FIRST(&ble_gattc_list) == entry);
+ STAILQ_REMOVE_HEAD(&ble_gattc_list, next);
+ } else {
+ assert(STAILQ_NEXT(prev, next) == entry);
+ STAILQ_NEXT(prev, next) = STAILQ_NEXT(entry, next);
+ }
+}
+
+static void
+ble_gattc_entry_remove_free(struct ble_gattc_entry *entry,
+ struct ble_gattc_entry *prev)
+{
+ ble_gattc_entry_remove(entry, prev);
+ ble_gattc_entry_free(entry);
+}
+
+static int
+ble_gattc_entry_matches(struct ble_gattc_entry *entry, uint16_t conn_handle,
+ uint8_t att_op, int expecting_only)
+{
+ if (conn_handle != entry->conn_handle) {
+ return 0;
+ }
+
+ if (att_op != entry->op && att_op != BLE_GATT_OP_NONE) {
+ return 0;
+ }
+
+ if (expecting_only &&
+ !(entry->flags & BLE_GATT_ENTRY_F_EXPECTING)) {
+
+ return 0;
+ }
+
+ return 1;
+}
+
+static struct ble_gattc_entry *
+ble_gattc_find(uint16_t conn_handle, uint8_t att_op, int expecting_only,
+ struct ble_gattc_entry **out_prev)
+{
+ struct ble_gattc_entry *entry;
+ struct ble_gattc_entry *prev;
+
+ prev = NULL;
+ STAILQ_FOREACH(entry, &ble_gattc_list, next) {
+ if (ble_gattc_entry_matches(entry, conn_handle, att_op,
+ expecting_only)) {
+ if (out_prev != NULL) {
+ *out_prev = prev;
+ }
+ return entry;
+ }
+
+ prev = entry;
+ }
+
+ return NULL;
+}
+
+static void
+ble_gattc_entry_set_pending(struct ble_gattc_entry *entry)
+{
+ assert(!(entry->flags & BLE_GATT_ENTRY_F_PENDING));
+
+ entry->flags &= ~BLE_GATT_ENTRY_F_EXPECTING;
+ entry->flags |= BLE_GATT_ENTRY_F_PENDING;
+ ble_hs_kick_gatt();
+}
+
+static void
+ble_gattc_entry_set_expecting(struct ble_gattc_entry *entry,
+ struct ble_gattc_entry *prev)
+{
+ assert(!(entry->flags & BLE_GATT_ENTRY_F_EXPECTING));
+
+ ble_gattc_entry_remove(entry, prev);
+ entry->flags &= ~BLE_GATT_ENTRY_F_PENDING;
+ entry->flags |= BLE_GATT_ENTRY_F_EXPECTING;
+ STAILQ_INSERT_TAIL(&ble_gattc_list, entry, next);
+}
+
+static int
+ble_gattc_new_entry(uint16_t conn_handle, uint8_t op,
+ struct ble_gattc_entry **entry)
+{
+ struct ble_hs_conn *conn;
+
+ *entry = NULL;
+
+ /* Ensure we have a connection with the specified handle. */
+ conn = ble_hs_conn_find(conn_handle);
+ if (conn == NULL) {
+ return BLE_HS_ENOTCONN;
+ }
+
+ *entry = ble_gattc_entry_alloc();
+ if (*entry == NULL) {
+ return BLE_HS_ENOMEM;
+ }
+
+ memset(*entry, 0, sizeof **entry);
+ (*entry)->op = op;
+ (*entry)->conn_handle = conn_handle;
+
+ STAILQ_INSERT_TAIL(&ble_gattc_list, *entry, next);
+
+ ble_gattc_entry_set_pending(*entry);
+
+ return 0;
+}
+
+static int
+ble_gattc_entry_can_pend(struct ble_gattc_entry *entry)
+{
+ return !(entry->flags & (BLE_GATT_ENTRY_F_CONGESTED |
+ BLE_GATT_ENTRY_F_NO_MEM |
+ BLE_GATT_ENTRY_F_EXPECTING));
+}
+
+static void
+ble_gattc_retx_timer_ensure(void)
+{
+ int rc;
+
+ rc = os_callout_reset(&ble_gattc_retx_timer.cf_c,
+ BLE_GATT_RETX_PERIOD * OS_TICKS_PER_SEC / 1000);
+ assert(rc == 0);
+}
+
+static void
+ble_gattc_retx_timer_exp(void *arg)
+{
+ struct ble_gattc_entry *entry;
+
+ STAILQ_FOREACH(entry, &ble_gattc_list, next) {
+ if (entry->flags & BLE_GATT_ENTRY_F_NO_MEM) {
+ entry->flags &= ~BLE_GATT_ENTRY_F_NO_MEM;
+ if (ble_gattc_entry_can_pend(entry)) {
+ ble_gattc_entry_set_pending(entry);
+ }
+ }
+ }
+}
+
+/**
+ * @return 1 if the transmit should be postponed; else 0.
+ */
+static int
+ble_gattc_tx_postpone_chk(struct ble_gattc_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_gattc_retx_timer_ensure();
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+/*****************************************************************************
+ * @mtu *
+ *****************************************************************************/
+
+static int
+ble_gattc_mtu_cb(struct ble_gattc_entry *entry, int status, uint16_t mtu)
+{
+ int rc;
+
+ if (entry->mtu.cb == NULL) {
+ rc = 0;
+ } else {
+ rc = entry->mtu.cb(entry->conn_handle, status, mtu, entry->mtu.cb_arg);
+ }
+
+ return rc;
+}
+
+static int
+ble_gattc_kick_mtu(struct ble_gattc_entry *entry)
+{
+ struct ble_att_mtu_cmd req;
+ struct ble_l2cap_chan *chan;
+ struct ble_hs_conn *conn;
+ int rc;
+
+ conn = ble_hs_conn_find(entry->conn_handle);
+ if (conn == NULL) {
+ rc = BLE_HS_ENOTCONN;
+ goto err;
+ }
+
+ chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
+ assert(chan != NULL);
+
+ req.bamc_mtu = chan->blc_my_mtu;
+ rc = ble_att_clt_tx_mtu(conn, &req);
+ if (rc != 0) {
+ goto err;
+ }
+
+ return 0;
+
+err:
+ if (ble_gattc_tx_postpone_chk(entry, rc)) {
+ return BLE_HS_EAGAIN;
+ }
+
+ ble_gattc_mtu_cb(entry, rc, 0);
+ return rc;
+}
+
+static void
+ble_gattc_err_mtu(struct ble_gattc_entry *entry, int status)
+{
+ ble_gattc_mtu_cb(entry, status, 0);
+}
+
+void
+ble_gattc_rx_mtu(struct ble_hs_conn *conn, uint16_t chan_mtu)
+{
+ struct ble_gattc_entry *entry;
+ struct ble_gattc_entry *prev;
+
+ entry = ble_gattc_find(conn->bhc_handle, BLE_GATT_OP_MTU, 1, &prev);
+ if (entry == NULL) {
+ /* Not expecting a response from this device. */
+ return;
+ }
+
+ ble_gattc_mtu_cb(entry, 0, chan_mtu);
+ ble_gattc_entry_remove_free(entry, prev);
+}
+
+int
+ble_gattc_exchange_mtu(uint16_t conn_handle)
+{
+ struct ble_gattc_entry *entry;
+ int rc;
+
+ rc = ble_gattc_new_entry(conn_handle, BLE_GATT_OP_MTU, &entry);
+ if (rc != 0) {
+ return rc;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+ * @discover all services *
+ *****************************************************************************/
+
+static int
+ble_gattc_disc_all_services_cb(struct ble_gattc_entry *entry,
+ int status, struct ble_gatt_service *service)
+{
+ int 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 rc;
+}
+
+static int
+ble_gattc_kick_disc_all_services(struct ble_gattc_entry *entry)
+{
+ 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) {
+ rc = BLE_HS_ENOTCONN;
+ goto err;
+ }
+
+ 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) {
+ goto err;
+ }
+
+ return 0;
+
+err:
+ if (ble_gattc_tx_postpone_chk(entry, rc)) {
+ return BLE_HS_EAGAIN;
+ }
+
+ ble_gattc_disc_all_services_cb(entry, rc, NULL);
+ return rc;
+}
+
+static void
+ble_gattc_err_disc_all_services(struct ble_gattc_entry *entry, int status)
+{
+ if (status == BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_FOUND)) {
+ /* Discovery is complete. */
+ status = 0;
+ }
+
+ ble_gattc_disc_all_services_cb(entry, status, NULL);
+}
+
+void
+ble_gattc_rx_read_group_type_adata(struct ble_hs_conn *conn,
+ struct ble_att_clt_adata *adata)
+{
+ struct ble_gatt_service service;
+ struct ble_gattc_entry *entry;
+ struct ble_gattc_entry *prev;
+ uint16_t uuid16;
+ int cbrc;
+ int rc;
+
+ entry = ble_gattc_find(conn->bhc_handle, BLE_GATT_OP_DISC_ALL_SERVICES, 1,
+ &prev);
+ if (entry == NULL) {
+ /* Not expecting a response from this device. */
+ return;
+ }
+
+ switch (adata->value_len) {
+ case 2:
+ uuid16 = le16toh(adata->value);
+ rc = ble_hs_uuid_from_16bit(uuid16, service.uuid128);
+ if (rc != 0) {
+ goto done;
+ }
+ break;
+
+ case 16:
+ memcpy(service.uuid128, adata->value, 16);
+ break;
+
+ default:
+ rc = BLE_HS_EMSGSIZE;
+ goto done;
+ }
+
+ entry->disc_all_services.prev_handle = adata->end_group_handle;
+
+ service.start_handle = adata->att_handle;
+ service.end_handle = adata->end_group_handle;
+
+ rc = 0;
+
+done:
+ cbrc = ble_gattc_disc_all_services_cb(entry, rc, &service);
+ if (rc != 0 || cbrc != 0) {
+ ble_gattc_entry_remove_free(entry, prev);
+ }
+}
+
+void
+ble_gattc_rx_read_group_type_complete(struct ble_hs_conn *conn, int rc)
+{
+ struct ble_gattc_entry *entry;
+ struct ble_gattc_entry *prev;
+
+ entry = ble_gattc_find(conn->bhc_handle, BLE_GATT_OP_DISC_ALL_SERVICES, 1,
+ &prev);
+ if (entry == NULL) {
+ /* Not expecting a response from this device. */
+ return;
+ }
+
+ if (rc != 0 || entry->disc_all_services.prev_handle == 0xffff) {
+ /* Error or all services discovered. */
+ ble_gattc_disc_all_services_cb(entry, rc, NULL);
+ ble_gattc_entry_remove_free(entry, prev);
+ } else {
+ /* Send follow-up request. */
+ ble_gattc_entry_set_pending(entry);
+ }
+}
+
+int
+ble_gattc_disc_all_services(uint16_t conn_handle, ble_gatt_disc_service_fn *cb,
+ void *cb_arg)
+{
+ struct ble_gattc_entry *entry;
+ int rc;
+
+ rc = ble_gattc_new_entry(conn_handle, BLE_GATT_OP_DISC_ALL_SERVICES,
+ &entry);
+ if (rc != 0) {
+ return rc;
+ }
+ 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_gattc_disc_service_uuid_cb(struct ble_gattc_entry *entry, int status,
+ struct ble_gatt_service *service)
+{
+ int rc;
+
+ if (entry->disc_service_uuid.cb == NULL) {
+ rc = 0;
+ } else {
+ rc = entry->disc_service_uuid.cb(entry->conn_handle, status, service,
+ entry->disc_service_uuid.cb_arg);
+ }
+
+ return rc;
+}
+
+static int
+ble_gattc_kick_disc_service_uuid(struct ble_gattc_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) {
+ rc = BLE_HS_ENOTCONN;
+ goto err;
+ }
+
+ 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) {
+ goto err;
+ }
+
+ return 0;
+
+err:
+ if (ble_gattc_tx_postpone_chk(entry, rc)) {
+ return BLE_HS_EAGAIN;
+ }
+
+ ble_gattc_disc_service_uuid_cb(entry, rc, NULL);
+ return rc;
+}
+
+static void
+ble_gattc_err_disc_service_uuid(struct ble_gattc_entry *entry, int status)
+{
+ if (status == BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_FOUND)) {
+ /* Discovery is complete. */
+ status = 0;
+ }
+
+ ble_gattc_disc_service_uuid_cb(entry, status, NULL);
+}
+
+void
+ble_gattc_rx_find_type_value_hinfo(struct ble_hs_conn *conn,
+ struct ble_att_clt_adata *adata)
+{
+ struct ble_gatt_service service;
+ struct ble_gattc_entry *entry;
+ struct ble_gattc_entry *prev;
+ int rc;
+
+ entry = ble_gattc_find(conn->bhc_handle, BLE_GATT_OP_DISC_SERVICE_UUID, 1,
+ &prev);
+ if (entry == NULL) {
+ /* Not expecting a response from this device. */
+ return;
+ }
+
+ entry->disc_service_uuid.prev_handle = adata->end_group_handle;
+
+ service.start_handle = adata->att_handle;
+ service.end_handle = adata->end_group_handle;
+ memcpy(service.uuid128, entry->disc_service_uuid.service_uuid, 16);
+
+ rc = ble_gattc_disc_service_uuid_cb(entry, 0, &service);
+ if (rc != 0) {
+ ble_gattc_entry_remove_free(entry, prev);
+ }
+}
+
+void
+ble_gattc_rx_find_type_value_complete(struct ble_hs_conn *conn, int rc)
+{
+ struct ble_gattc_entry *entry;
+ struct ble_gattc_entry *prev;
+
+ entry = ble_gattc_find(conn->bhc_handle, BLE_GATT_OP_DISC_SERVICE_UUID, 1,
+ &prev);
+ if (entry == NULL) {
+ /* Not expecting a response from this device. */
+ return;
+ }
+
+ if (rc != 0 || entry->disc_service_uuid.prev_handle == 0xffff) {
+ /* Error or all services discovered. */
+ ble_gattc_disc_service_uuid_cb(entry, rc, NULL);
+ ble_gattc_entry_remove_free(entry, prev);
+ } else {
+ /* Send follow-up request. */
+ ble_gattc_entry_set_pending(entry);
+ }
+}
+
+int
+ble_gattc_disc_service_by_uuid(uint16_t conn_handle, void *service_uuid128,
+ ble_gatt_disc_service_fn *cb, void *cb_arg)
+{
+ struct ble_gattc_entry *entry;
+ int rc;
+
+ rc = ble_gattc_new_entry(conn_handle, BLE_GATT_OP_DISC_SERVICE_UUID,
+ &entry);
+ if (rc != 0) {
+ return rc;
+ }
+ 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_gattc_disc_all_chars_cb(struct ble_gattc_entry *entry, int status,
+ struct ble_gatt_chr *chr)
+{
+ int rc;
+
+ if (entry->disc_all_chars.cb == NULL) {
+ rc = 0;
+ } else {
+ rc = entry->disc_all_chars.cb(entry->conn_handle, status, chr,
+ entry->disc_all_chars.cb_arg);
+ }
+
+ return rc;
+}
+
+static int
+ble_gattc_kick_disc_all_chars(struct ble_gattc_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) {
+ rc = BLE_HS_ENOTCONN;
+ goto err;
+ }
+
+ 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) {
+ goto err;
+ }
+
+ return 0;
+
+err:
+ if (ble_gattc_tx_postpone_chk(entry, rc)) {
+ return BLE_HS_EAGAIN;
+ }
+
+ ble_gattc_disc_all_chars_cb(entry, rc, NULL);
+ return rc;
+}
+
+static void
+ble_gattc_err_disc_all_chars(struct ble_gattc_entry *entry, int status)
+{
+ if (status == BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_FOUND)) {
+ /* Discovery is complete. */
+ status = 0;
+ }
+
+ ble_gattc_disc_all_chars_cb(entry, status, NULL);
+}
+
+void
+ble_gattc_rx_read_type_adata(struct ble_hs_conn *conn,
+ struct ble_att_clt_adata *adata)
+{
+ struct ble_gattc_entry *entry;
+ struct ble_gattc_entry *prev;
+ struct ble_gatt_chr chr;
+ uint16_t uuid16;
+ int cbrc;
+ int rc;
+
+ entry = ble_gattc_find(conn->bhc_handle, BLE_GATT_OP_DISC_ALL_CHARS, 1,
+ &prev);
+ if (entry == NULL) {
+ /* Not expecting a response from this device. */
+ return;
+ }
+
+ memset(&chr, 0, sizeof chr);
+ chr.decl_handle = adata->att_handle;
+
+ switch (adata->value_len) {
+ case BLE_GATT_CHR_DECL_SZ_16:
+ uuid16 = le16toh(adata->value + 3);
+ rc = ble_hs_uuid_from_16bit(uuid16, chr.uuid128);
+ if (rc != 0) {
+ rc = BLE_HS_EBADDATA;
+ goto done;
+ }
+ break;
+
+ case BLE_GATT_CHR_DECL_SZ_128:
+ memcpy(chr.uuid128, adata->value + 3, 16);
+ break;
+
+ default:
+ rc = BLE_HS_EBADDATA;
+ goto done;
+ }
+
+ entry->disc_all_chars.prev_handle = adata->att_handle;
+
+ chr.properties = adata->value[0];
+ chr.value_handle = le16toh(adata->value + 1);
+
+ rc = 0;
+
+done:
+ cbrc = ble_gattc_disc_all_chars_cb(entry, rc, &chr);
+ if (rc != 0 || cbrc != 0) {
+ ble_gattc_entry_remove_free(entry, prev);
+ }
+}
+
+void
+ble_gattc_rx_read_type_complete(struct ble_hs_conn *conn, int rc)
+{
+ struct ble_gattc_entry *entry;
+ struct ble_gattc_entry *prev;
+
+ entry = ble_gattc_find(conn->bhc_handle, BLE_GATT_OP_DISC_ALL_CHARS, 1,
+ &prev);
+ if (entry == NULL) {
+ /* Not expecting a response from this device. */
+ return;
+ }
+
+ if (rc != 0 || entry->disc_all_chars.prev_handle ==
+ entry->disc_all_chars.end_handle) {
+ /* Error or all services discovered. */
+ ble_gattc_disc_all_chars_cb(entry, rc, NULL);
+ ble_gattc_entry_remove_free(entry, prev);
+ } else {
+ /* Send follow-up request. */
+ ble_gattc_entry_set_pending(entry);
+ }
+}
+
+int
+ble_gattc_disc_all_chars(uint16_t conn_handle, uint16_t start_handle,
+ uint16_t end_handle, ble_gatt_chr_fn *cb,
+ void *cb_arg)
+{
+ struct ble_gattc_entry *entry;
+ int rc;
+
+ rc = ble_gattc_new_entry(conn_handle, BLE_GATT_OP_DISC_ALL_CHARS, &entry);
+ if (rc != 0) {
+ return rc;
+ }
+ 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_gattc_read_cb(struct ble_gattc_entry *entry, int status,
+ struct ble_gatt_attr *attr)
+{
+ int rc;
+
+ if (entry->read.cb == NULL) {
+ rc = 0;
+ } else {
+ rc = entry->read.cb(entry->conn_handle, status, attr,
+ entry->read.cb_arg);
+ }
+
+ return rc;
+}
+
+static int
+ble_gattc_kick_read(struct ble_gattc_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) {
+ rc = BLE_HS_ENOTCONN;
+ goto err;
+ }
+
+ req.barq_handle = entry->read.handle;
+ rc = ble_att_clt_tx_read(conn, &req);
+ if (rc != 0) {
+ goto err;
+ }
+
+ return 0;
+
+err:
+ if (ble_gattc_tx_postpone_chk(entry, rc)) {
+ return BLE_HS_EAGAIN;
+ }
+
+ ble_gattc_read_cb(entry, rc, NULL);
+ return rc;
+}
+
+static void
+ble_gattc_err_read(struct ble_gattc_entry *entry, int status)
+{
+ ble_gattc_read_cb(entry, status, NULL);
+}
+
+void
+ble_gattc_rx_read_rsp(struct ble_hs_conn *conn, int status, void *value,
+ int value_len)
+{
+ struct ble_gattc_entry *entry;
+ struct ble_gattc_entry *prev;
+ struct ble_gatt_attr attr;
+
+ entry = ble_gattc_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;
+
+ ble_gattc_read_cb(entry, status, &attr);
+
+ /* The read operation only has a single request / response exchange. */
+ ble_gattc_entry_remove_free(entry, prev);
+}
+
+int
+ble_gattc_read(uint16_t conn_handle, uint16_t attr_handle,
+ ble_gatt_attr_fn *cb, void *cb_arg)
+{
+ struct ble_gattc_entry *entry;
+ int rc;
+
+ rc = ble_gattc_new_entry(conn_handle, BLE_GATT_OP_READ, &entry);
+ if (rc != 0) {
+ return rc;
+ }
+ entry->read.handle = attr_handle;
+ entry->read.cb = cb;
+ entry->read.cb_arg = cb_arg;
+
+ return 0;
+}
+
+/*****************************************************************************
+ * @write no response *
+ *****************************************************************************/
+
+static int
+ble_gattc_write_cb(struct ble_gattc_entry *entry, int status)
+{
+ int rc;
+
+ if (entry->write.cb == NULL) {
+ rc = 0;
+ } else {
+ rc = entry->write.cb(entry->conn_handle, status, &entry->write.attr,
+ entry->write.cb_arg);
+ }
+
+ return rc;
+}
+
+static int
+ble_gattc_kick_write_no_rsp(struct ble_gattc_entry *entry)
+{
+ struct ble_att_write_req req;
+ struct ble_hs_conn *conn;
+ int rc;
+
+ conn = ble_hs_conn_find(entry->conn_handle);
+ if (conn == NULL) {
+ rc = BLE_HS_ENOTCONN;
+ goto err;
+ }
+
+ req.bawq_handle = entry->write.attr.handle;
+ rc = ble_att_clt_tx_write_cmd(conn, &req, entry->write.attr.value,
+ entry->write.attr.value_len);
+ if (rc != 0) {
+ goto err;
+ }
+
+ /* No response expected; call callback immediately and return nonzero to
+ * indicate the entry should be freed.
+ */
+ ble_gattc_write_cb(entry, 0);
+
+ return 1;
+
+err:
+ if (ble_gattc_tx_postpone_chk(entry, rc)) {
+ return BLE_HS_EAGAIN;
+ }
+
+ ble_gattc_write_cb(entry, rc);
+ return rc;
+}
+
+int
+ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle, void *value,
+ uint16_t value_len, ble_gatt_attr_fn *cb, void *cb_arg)
+{
+ struct ble_gattc_entry *entry;
+ int rc;
+
+ rc = ble_gattc_new_entry(conn_handle, BLE_GATT_OP_WRITE_NO_RSP, &entry);
+ if (rc != 0) {
+ return rc;
+ }
+
+ entry->write.attr.handle = attr_handle;
+ entry->write.attr.value = value;
+ entry->write.attr.value_len = value_len;
+ entry->write.cb = cb;
+ entry->write.cb_arg = cb_arg;
+
+ return 0;
+}
+
+/*****************************************************************************
+ * @write *
+ *****************************************************************************/
+
+static int
+ble_gattc_kick_write(struct ble_gattc_entry *entry)
+{
+ struct ble_att_write_req req;
+ struct ble_hs_conn *conn;
+ int rc;
+
+ conn = ble_hs_conn_find(entry->conn_handle);
+ if (conn == NULL) {
+ rc = BLE_HS_ENOTCONN;
+ goto err;
+ }
+
+ req.bawq_handle = entry->write.attr.handle;
+ rc = ble_att_clt_tx_write_req(conn, &req, entry->write.attr.value,
+ entry->write.attr.value_len);
+ if (rc != 0) {
+ goto err;
+ }
+
+ return 0;
+
+err:
+ if (ble_gattc_tx_postpone_chk(entry, rc)) {
+ return BLE_HS_EAGAIN;
+ }
+
+ ble_gattc_write_cb(entry, rc);
+ return rc;
+}
+
+static void
+ble_gattc_err_write(struct ble_gattc_entry *entry, int status)
+{
+ ble_gattc_write_cb(entry, status);
+}
+
+void
+ble_gattc_rx_write_rsp(struct ble_hs_conn *conn)
+{
+ struct ble_gattc_entry *entry;
+ struct ble_gattc_entry *prev;
+
+ entry = ble_gattc_find(conn->bhc_handle, BLE_GATT_OP_WRITE, 1, &prev);
+ if (entry == NULL) {
+ /* Not expecting a response from this device. */
+ return;
+ }
+
+ ble_gattc_write_cb(entry, 0);
+
+ /* The write operation only has a single request / response exchange. */
+ ble_gattc_entry_remove_free(entry, prev);
+}
+
+int
+ble_gattc_write(uint16_t conn_handle, uint16_t attr_handle, void *value,
+ uint16_t value_len, ble_gatt_attr_fn *cb, void *cb_arg)
+{
+ struct ble_gattc_entry *entry;
+ int rc;
+
+ rc = ble_gattc_new_entry(conn_handle, BLE_GATT_OP_WRITE, &entry);
+ if (rc != 0) {
+ return rc;
+ }
+
+ entry->write.attr.handle = attr_handle;
+ entry->write.attr.value = value;
+ entry->write.attr.value_len = value_len;
+ entry->write.cb = cb;
+ entry->write.cb_arg = cb_arg;
+
+ return 0;
+}
+
+/*****************************************************************************
+ * @misc *
+ *****************************************************************************/
+
+void
+ble_gattc_wakeup(void)
+{
+ const struct ble_gattc_dispatch_entry *dispatch;
+ struct ble_gattc_entry *entry;
+ struct ble_gattc_entry *prev;
+ struct ble_gattc_entry *next;
+ int rc;
+
+ prev = NULL;
+ entry = STAILQ_FIRST(&ble_gattc_list);
+ while (entry != NULL) {
+ next = STAILQ_NEXT(entry, next);
+
+ if (entry->flags & BLE_GATT_ENTRY_F_PENDING) {
+ dispatch = ble_gattc_dispatch_get(entry->op);
+ rc = dispatch->kick_cb(entry);
+ switch (rc) {
+ case 0:
+ /* Transmit succeeded. Response expected. */
+ ble_gattc_entry_set_expecting(entry, prev);
+ /* Current entry got moved to back; old prev still valid. */
+ break;
+
+ case BLE_HS_EAGAIN:
+ /* Transmit failed due to resource shortage. Reschedule. */
+ entry->flags &= ~BLE_GATT_ENTRY_F_PENDING;
+ /* Current entry remains; reseat prev. */
+ prev = entry;
+ break;
+
+ default:
+ /* Transmit failed. Abort procedure. */
+ ble_gattc_entry_remove_free(entry, prev);
+ /* Current entry removed; old prev still valid. */
+ break;
+ }
+ } else {
+ prev = entry;
+ }
+
+ entry = next;
+ }
+}
+
+void
+ble_gattc_rx_err(uint16_t conn_handle, struct ble_att_error_rsp *rsp)
+{
+ const struct ble_gattc_dispatch_entry *dispatch;
+ struct ble_gattc_entry *entry;
+ struct ble_gattc_entry *prev;
+
+ entry = ble_gattc_find(conn_handle, BLE_GATT_OP_NONE, 1, &prev);
+ if (entry == NULL) {
+ /* Not expecting a response from this device. */
+ return;
+ }
+
+ dispatch = ble_gattc_dispatch_get(entry->op);
+ if (dispatch->err_cb != NULL) {
+ dispatch->err_cb(entry, BLE_HS_ERR_ATT_BASE + rsp->baep_error_code);
+ }
+
+ ble_gattc_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_gattc_connection_broken(uint16_t conn_handle)
+{
+ const struct ble_gattc_dispatch_entry *dispatch;
+ struct ble_gattc_entry *entry;
+ struct ble_gattc_entry *prev;
+
+ while (1) {
+ entry = ble_gattc_find(conn_handle, BLE_GATT_OP_NONE, 0, &prev);
+ if (entry == NULL) {
+ break;
+ }
+
+ dispatch = ble_gattc_dispatch_get(entry->op);
+ dispatch->err_cb(entry, BLE_HS_ENOTCONN);
+
+ ble_gattc_entry_remove_free(entry, prev);
+ }
+}
+
+/**
+ * Called when a BLE connection transitions into a transmittable state. Wakes
+ * up all congested GATT procedures associated with the connection.
+ */
+void
+ble_gattc_connection_txable(uint16_t conn_handle)
+{
+ struct ble_gattc_entry *entry;
+
+ STAILQ_FOREACH(entry, &ble_gattc_list, next) {
+ if (entry->conn_handle == conn_handle &&
+ entry->flags & BLE_GATT_ENTRY_F_CONGESTED) {
+
+ entry->flags &= ~BLE_GATT_ENTRY_F_CONGESTED;
+ if (ble_gattc_entry_can_pend(entry)) {
+ ble_gattc_entry_set_pending(entry);
+ }
+ }
+ }
+}
+
+int
+ble_gattc_init(void)
+{
+ int rc;
+
+ free(ble_gattc_entry_mem);
+
+ ble_gattc_entry_mem = malloc(
+ OS_MEMPOOL_BYTES(BLE_GATT_NUM_ENTRIES,
+ sizeof (struct ble_gattc_entry)));
+ if (ble_gattc_entry_mem == NULL) {
+ rc = BLE_HS_ENOMEM;
+ goto err;
+ }
+
+ rc = os_mempool_init(&ble_gattc_entry_pool,
+ BLE_GATT_NUM_ENTRIES,
+ sizeof (struct ble_gattc_entry),
+ ble_gattc_entry_mem,
+ "ble_gattc_entry_pool");
+ if (rc != 0) {
+ goto err;
+ }
+
+ STAILQ_INIT(&ble_gattc_list);
+
+ os_callout_func_init(&ble_gattc_retx_timer, &ble_hs_evq,
+ ble_gattc_retx_timer_exp, NULL);
+
+ return 0;
+
+err:
+ free(ble_gattc_entry_mem);
+ ble_gattc_entry_mem = NULL;
+
+ return rc;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/2c857eba/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 c7473d0..416e459 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -134,7 +134,7 @@ ble_hs_task_handler(void *arg)
break;
case BLE_HS_KICK_GATT_EVENT:
- ble_gatt_wakeup();
+ ble_gattc_wakeup();
break;
default:
@@ -263,7 +263,7 @@ ble_hs_init(uint8_t prio)
return rc;
}
- rc = ble_gatt_init();
+ rc = ble_gattc_init();
if (rc != 0) {
return rc;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/2c857eba/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 6c29ecf..4e0fc32 100644
--- a/net/nimble/host/src/ble_hs_conn.c
+++ b/net/nimble/host/src/ble_hs_conn.c
@@ -145,7 +145,7 @@ ble_hs_conn_chan_find(struct ble_hs_conn *conn, uint16_t cid)
static void
ble_hs_conn_txable_transition(struct ble_hs_conn *conn)
{
- ble_gatt_connection_txable(conn->bhc_handle);
+ ble_gattc_connection_txable(conn->bhc_handle);
}
void
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/2c857eba/net/nimble/host/src/test/ble_gatt_conn_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gatt_conn_test.c b/net/nimble/host/src/test/ble_gatt_conn_test.c
index c52b538..cefbc3a 100644
--- a/net/nimble/host/src/test/ble_gatt_conn_test.c
+++ b/net/nimble/host/src/test/ble_gatt_conn_test.c
@@ -146,7 +146,7 @@ TEST_CASE(ble_gatt_conn_test_disconnect)
TEST_ASSERT_FATAL(rc == 0);
/* Start the procedures. */
- ble_gatt_wakeup();
+ ble_gattc_wakeup();
/* Break the connections; verify callbacks got called. */
ble_gatt_connection_broken(BLE_GATT_BREAK_TEST_DISC_SERVICE_HANDLE);
@@ -181,14 +181,14 @@ TEST_CASE(ble_gatt_conn_test_congestion)
rc = ble_gatt_write(1, 0x1234, ble_gatt_conn_test_write_value,
sizeof ble_gatt_conn_test_write_value, NULL, NULL);
TEST_ASSERT_FATAL(rc == 0);
- ble_gatt_wakeup();
+ ble_gattc_wakeup();
ble_hs_process_tx_data_queue();
/* Ensure only one packet got sent. */
TEST_ASSERT(conn->bhc_outstanding_pkts == 1);
/* Additional wakeups should not trigger the second send. */
- ble_gatt_wakeup();
+ ble_gattc_wakeup();
ble_hs_process_tx_data_queue();
TEST_ASSERT(conn->bhc_outstanding_pkts == 1);
@@ -202,7 +202,7 @@ TEST_CASE(ble_gatt_conn_test_congestion)
TEST_ASSERT(conn->bhc_outstanding_pkts == 0);
/* Now the second write should get sent. */
- ble_gatt_wakeup();
+ ble_gattc_wakeup();
ble_hs_process_tx_data_queue();
TEST_ASSERT(conn->bhc_outstanding_pkts == 1);
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/2c857eba/net/nimble/host/src/test/ble_gatt_disc_c_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gatt_disc_c_test.c b/net/nimble/host/src/test/ble_gatt_disc_c_test.c
index 19857c9..5a62704 100644
--- a/net/nimble/host/src/test/ble_gatt_disc_c_test.c
+++ b/net/nimble/host/src/test/ble_gatt_disc_c_test.c
@@ -62,7 +62,7 @@ ble_gatt_disc_c_test_misc_rx_all_rsp_once(
int i;
/* Send the pending ATT Read By Type Request. */
- ble_gatt_wakeup();
+ ble_gattc_wakeup();
ble_hs_process_tx_data_queue();
if (chars[0].uuid16 != 0) {
@@ -134,7 +134,7 @@ ble_gatt_disc_c_test_misc_rx_all_rsp(struct ble_hs_conn *conn,
if (chars[idx - 1].decl_handle != end_handle) {
/* Send the pending ATT Request. */
- ble_gatt_wakeup();
+ ble_gattc_wakeup();
ble_hs_test_util_rx_att_err_rsp(conn, BLE_ATT_OP_READ_TYPE_REQ,
BLE_ATT_ERR_ATTR_NOT_FOUND,
chars[idx - 1].decl_handle);
@@ -200,7 +200,7 @@ ble_gatt_disc_c_test_misc_all(uint16_t start_handle, uint16_t end_handle,
conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}));
rc = ble_gatt_disc_all_chars(2, start_handle, end_handle,
- ble_gatt_disc_c_test_misc_cb, NULL);
+ ble_gatt_disc_c_test_misc_cb, NULL);
TEST_ASSERT(rc == 0);
ble_gatt_disc_c_test_misc_rx_all_rsp(conn, end_handle, chars);