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:35 UTC
[6/6] incubator-mynewt-larva git commit: Fix bug: ATT server silent
when read-type done!
Fix bug: ATT server silent when read-type done!
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/ba4a7ed2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/ba4a7ed2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/ba4a7ed2
Branch: refs/heads/master
Commit: ba4a7ed2b053c74533e1f7c4e8a5c60c2938c893
Parents: 51bd2b4
Author: Christopher Collins <cc...@gmail.com>
Authored: Wed Dec 23 14:50:30 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Wed Dec 23 15:33:49 2015 -0800
----------------------------------------------------------------------
net/nimble/host/src/ble_att_svr.c | 20 +-
net/nimble/host/src/test/ble_att_svr_test.c | 252 ++++++++++++++++++++++-
2 files changed, 256 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ba4a7ed2/net/nimble/host/src/ble_att_svr.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_svr.c b/net/nimble/host/src/ble_att_svr.c
index 932e064..4975d65 100644
--- a/net/nimble/host/src/ble_att_svr.c
+++ b/net/nimble/host/src/ble_att_svr.c
@@ -961,14 +961,16 @@ ble_att_svr_tx_read_type_rsp(struct ble_hs_conn *conn,
struct ble_att_svr_entry *entry;
struct os_mbuf *txom;
uint8_t *dptr;
+ int entry_written;
int txomlen;
int prev_attr_len;
int attr_len;
int rc;
*att_err = 0; /* Silence unnecessary warning. */
- *err_handle = 0; /* Silence unnecessary warning. */
+ *err_handle = req->batq_start_handle;
+ entry_written = 0;
prev_attr_len = 0;
txom = ble_att_get_pkthdr();
@@ -1006,9 +1008,7 @@ ble_att_svr_tx_read_type_rsp(struct ble_hs_conn *conn,
break;
}
- if (entry->ha_handle_id >= req->batq_start_handle &&
- entry->ha_handle_id <= req->batq_end_handle) {
-
+ if (entry->ha_handle_id >= req->batq_start_handle) {
rc = entry->ha_cb(entry->ha_handle_id, entry->ha_uuid,
BLE_ATT_ACCESS_OP_READ, &arg, entry->ha_cb_arg);
if (rc != 0) {
@@ -1044,11 +1044,12 @@ ble_att_svr_tx_read_type_rsp(struct ble_hs_conn *conn,
htole16(dptr + 0, entry->ha_handle_id);
memcpy(dptr + 2, arg.ahc_read.attr_data, attr_len);
+ entry_written = 1;
}
}
done:
- if (OS_MBUF_PKTLEN(txom) == 0) {
+ if (!entry_written) {
/* No matching attributes. */
if (*att_err == 0) {
*att_err = BLE_ATT_ERR_ATTR_NOT_FOUND;
@@ -1098,6 +1099,15 @@ ble_att_svr_rx_read_type(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
rc = ble_att_read_type_req_parse((*rxom)->om_data, (*rxom)->om_len, &req);
assert(rc == 0);
+ if (req.batq_start_handle > req.batq_end_handle ||
+ req.batq_start_handle == 0) {
+
+ att_err = BLE_ATT_ERR_INVALID_HANDLE;
+ err_handle = req.batq_start_handle;
+ rc = BLE_HS_EBADDATA;
+ goto err;
+ }
+
switch ((*rxom)->om_len) {
case BLE_ATT_READ_TYPE_REQ_SZ_16:
uuid16 = le16toh((*rxom)->om_data + 5);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ba4a7ed2/net/nimble/host/src/test/ble_att_svr_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_att_svr_test.c b/net/nimble/host/src/test/ble_att_svr_test.c
index 3562210..4b7372f 100644
--- a/net/nimble/host/src/test/ble_att_svr_test.c
+++ b/net/nimble/host/src/test/ble_att_svr_test.c
@@ -102,21 +102,21 @@ ble_att_svr_test_misc_attr_fn_r_group(uint16_t handle_id, uint8_t *uuid128,
static uint8_t vals[20][16] = {
[1] = { 0x22, 0x11 },
- [2] = { 0xdd, 0xdd },
- [3] = { 0xdd, 0xdd },
- [4] = { 0xdd, 0xdd },
- [5] = { 0xdd, 0xdd },
+ [2] = { 0x01, 0x11 },
+ [3] = { 0x02, 0x11 },
+ [4] = { 0x03, 0x11 },
+ [5] = { 0x04, 0x11 },
[6] = { 0x33, 0x22 },
- [7] = { 0xee, 0xee },
- [8] = { 0xee, 0xee },
- [9] = { 0xee, 0xee },
- [10] = { 0xee, 0xee },
+ [7] = { 0x01, 0x22 },
+ [8] = { 0x02, 0x22 },
+ [9] = { 0x03, 0x22 },
+ [10] = { 0x04, 0x22 },
[11] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 },
- [12] = { 0xdd, 0xdd },
+ [12] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
[13] = { 0xdd, 0xdd },
- [14] = { 0xdd, 0xdd },
+ [14] = { 0x55, 0x55 },
[15] = { 0xdd, 0xdd },
- [16] = { 0xdd, 0xdd },
+ [16] = { 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 },
[17] = { 0xdd, 0xdd },
[18] = { 0xdd, 0xdd },
[19] = { 0xdd, 0xdd },
@@ -544,6 +544,56 @@ ble_att_svr_test_misc_verify_tx_read_group_type_rsp(
TEST_ASSERT(off == OS_MBUF_PKTLEN(om));
}
+struct ble_att_svr_test_type_entry {
+ uint16_t handle; /* 0 on last entry */
+ void *value;
+ int value_len;
+};
+
+/** Returns the number of entries successfully verified. */
+static void
+ble_att_svr_test_misc_verify_tx_read_type_rsp(
+ struct ble_l2cap_chan *chan,
+ struct ble_att_svr_test_type_entry *entries)
+{
+ struct ble_att_svr_test_type_entry *entry;
+ struct ble_att_read_type_rsp rsp;
+ struct os_mbuf *om;
+ uint16_t handle;
+ uint8_t buf[512];
+ int off;
+ int rc;
+
+ ble_hs_process_tx_data_queue();
+
+ om = os_mbuf_pullup(ble_hs_test_util_prev_tx,
+ BLE_ATT_READ_TYPE_RSP_BASE_SZ);
+ TEST_ASSERT_FATAL(om != NULL);
+
+ rc = ble_att_read_type_rsp_parse(om->om_data, om->om_len, &rsp);
+ TEST_ASSERT(rc == 0);
+
+ off = BLE_ATT_READ_TYPE_RSP_BASE_SZ;
+ for (entry = entries; entry->handle != 0; entry++) {
+ TEST_ASSERT_FATAL(rsp.batp_length ==
+ BLE_ATT_READ_TYPE_ADATA_BASE_SZ + entry->value_len);
+
+ rc = os_mbuf_copydata(om, off, 2, &handle);
+ TEST_ASSERT(rc == 0);
+ handle = le16toh(&handle);
+ TEST_ASSERT(handle == entry->handle);
+ off += 2;
+
+ rc = os_mbuf_copydata(om, off, entry->value_len, buf);
+ TEST_ASSERT(rc == 0);
+ TEST_ASSERT(memcmp(entry->value, buf, entry->value_len) == 0);
+ off += entry->value_len;
+ }
+
+ /* Ensure there is no extra data in the response. */
+ TEST_ASSERT(off == OS_MBUF_PKTLEN(om));
+}
+
static void
ble_att_svr_test_misc_verify_tx_prep_write_rsp(struct ble_l2cap_chan *chan,
uint16_t attr_handle,
@@ -1140,6 +1190,185 @@ TEST_CASE(ble_att_svr_test_find_type_value)
} }));
}
+TEST_CASE(ble_att_svr_test_read_type)
+{
+ struct ble_att_read_type_req req;
+ struct ble_l2cap_chan *chan;
+ struct ble_hs_conn *conn;
+ uint8_t buf[BLE_ATT_READ_TYPE_REQ_SZ_16];
+ int rc;
+
+ ble_att_svr_test_misc_init(&conn, &chan);
+
+ /* Increase the MTU to 128 bytes to allow testing of long responses. */
+ chan->blc_my_mtu = 128;
+ chan->blc_peer_mtu = 128;
+ chan->blc_flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
+
+ /*** Start handle of 0. */
+ req.batq_start_handle = 0;
+ req.batq_end_handle = 0;
+
+ rc = ble_att_read_type_req_write(buf, sizeof buf, &req);
+ TEST_ASSERT(rc == 0);
+ htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
+ BLE_ATT_UUID_PRIMARY_SERVICE);
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+ TEST_ASSERT(rc != 0);
+ ble_att_svr_test_misc_verify_tx_err_rsp(
+ chan, BLE_ATT_OP_READ_TYPE_REQ, 0,
+ BLE_ATT_ERR_INVALID_HANDLE);
+
+ /*** Start handle > end handle. */
+ req.batq_start_handle = 101;
+ req.batq_end_handle = 100;
+
+ rc = ble_att_read_type_req_write(buf, sizeof buf, &req);
+ TEST_ASSERT(rc == 0);
+ htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
+ BLE_ATT_UUID_PRIMARY_SERVICE);
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+ TEST_ASSERT(rc != 0);
+ ble_att_svr_test_misc_verify_tx_err_rsp(
+ chan, BLE_ATT_OP_READ_TYPE_REQ, 101,
+ BLE_ATT_ERR_INVALID_HANDLE);
+
+ /*** No attributes. */
+ req.batq_start_handle = 1;
+ req.batq_end_handle = 0xffff;
+
+ rc = ble_att_read_type_req_write(buf, sizeof buf, &req);
+ TEST_ASSERT(rc == 0);
+ htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
+ BLE_ATT_UUID_PRIMARY_SERVICE);
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+ TEST_ASSERT(rc != 0);
+ ble_att_svr_test_misc_verify_tx_err_rsp(
+ chan, BLE_ATT_OP_READ_TYPE_REQ, 1,
+ BLE_ATT_ERR_ATTR_NOT_FOUND);
+
+ /*** Range too late. */
+ ble_att_svr_test_misc_register_group_attrs();
+ req.batq_start_handle = 200;
+ req.batq_end_handle = 300;
+
+ rc = ble_att_read_type_req_write(buf, sizeof buf, &req);
+ TEST_ASSERT(rc == 0);
+ htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
+ BLE_ATT_UUID_PRIMARY_SERVICE);
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+ TEST_ASSERT(rc != 0);
+ ble_att_svr_test_misc_verify_tx_err_rsp(
+ chan, BLE_ATT_OP_READ_TYPE_REQ, 200,
+ BLE_ATT_ERR_ATTR_NOT_FOUND);
+
+ /*** One characteristic from one service. */
+ req.batq_start_handle = 1;
+ req.batq_end_handle = 2;
+
+ rc = ble_att_read_type_req_write(buf, sizeof buf, &req);
+ TEST_ASSERT(rc == 0);
+ htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
+ BLE_ATT_UUID_CHARACTERISTIC);
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+ TEST_ASSERT(rc == 0);
+ ble_att_svr_test_misc_verify_tx_read_type_rsp(chan,
+ ((struct ble_att_svr_test_type_entry[]) { {
+ .handle = 2,
+ .value = (uint8_t[]){ 0x01, 0x11 },
+ .value_len = 2,
+ }, {
+ .handle = 0,
+ } }));
+
+ /*** Both characteristics from one service. */
+ req.batq_start_handle = 1;
+ req.batq_end_handle = 10;
+
+ rc = ble_att_read_type_req_write(buf, sizeof buf, &req);
+ TEST_ASSERT(rc == 0);
+ htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
+ BLE_ATT_UUID_CHARACTERISTIC);
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+ TEST_ASSERT(rc == 0);
+ ble_att_svr_test_misc_verify_tx_read_type_rsp(chan,
+ ((struct ble_att_svr_test_type_entry[]) { {
+ .handle = 2,
+ .value = (uint8_t[]){ 0x01, 0x11 },
+ .value_len = 2,
+ }, {
+ .handle = 4,
+ .value = (uint8_t[]){ 0x03, 0x11 },
+ .value_len = 2,
+ }, {
+ .handle = 0,
+ } }));
+
+ /*** Ensure 16-bit and 128-bit values are retrieved separately. */
+ req.batq_start_handle = 11;
+ req.batq_end_handle = 0xffff;
+
+ rc = ble_att_read_type_req_write(buf, sizeof buf, &req);
+ TEST_ASSERT(rc == 0);
+ htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
+ BLE_ATT_UUID_CHARACTERISTIC);
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+ TEST_ASSERT(rc == 0);
+ ble_att_svr_test_misc_verify_tx_read_type_rsp(chan,
+ ((struct ble_att_svr_test_type_entry[]) { {
+ .handle = 12,
+ .value = (uint8_t[]){ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
+ .value_len = 16,
+ }, {
+ .handle = 0,
+ } }));
+
+ req.batq_start_handle = 13;
+ req.batq_end_handle = 0xffff;
+
+ rc = ble_att_read_type_req_write(buf, sizeof buf, &req);
+ TEST_ASSERT(rc == 0);
+ htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
+ BLE_ATT_UUID_CHARACTERISTIC);
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+ TEST_ASSERT(rc == 0);
+ ble_att_svr_test_misc_verify_tx_read_type_rsp(chan,
+ ((struct ble_att_svr_test_type_entry[]) { {
+ .handle = 14,
+ .value = (uint8_t[]){ 0x55, 0x55 },
+ .value_len = 2,
+ }, {
+ .handle = 0,
+ } }));
+
+ req.batq_start_handle = 15;
+ req.batq_end_handle = 0xffff;
+
+ rc = ble_att_read_type_req_write(buf, sizeof buf, &req);
+ TEST_ASSERT(rc == 0);
+ htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
+ BLE_ATT_UUID_CHARACTERISTIC);
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+ TEST_ASSERT(rc == 0);
+ ble_att_svr_test_misc_verify_tx_read_type_rsp(chan,
+ ((struct ble_att_svr_test_type_entry[]) { {
+ .handle = 16,
+ .value = (uint8_t[]){ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 },
+ .value_len = 16,
+ }, {
+ .handle = 0,
+ } }));
+}
+
TEST_CASE(ble_att_svr_test_read_group_type)
{
struct ble_att_read_group_type_req req;
@@ -1443,6 +1672,7 @@ TEST_SUITE(ble_att_svr_suite)
ble_att_svr_test_write();
ble_att_svr_test_find_info();
ble_att_svr_test_find_type_value();
+ ble_att_svr_test_read_type();
ble_att_svr_test_read_group_type();
ble_att_svr_test_prep_write();
}