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 2016/09/13 03:42:04 UTC
[11/41] incubator-mynewt-core git commit: syscfg / sysinit
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/net/nimble/host/test/src/ble_gatt_conn_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_gatt_conn_test.c b/net/nimble/host/test/src/ble_gatt_conn_test.c
new file mode 100644
index 0000000..be4a46d
--- /dev/null
+++ b/net/nimble/host/test/src/ble_gatt_conn_test.c
@@ -0,0 +1,533 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 <string.h>
+#include <errno.h>
+#include "testutil/testutil.h"
+#include "nimble/ble.h"
+#include "host/ble_hs_test.h"
+#include "ble_hs_test_util.h"
+
+#define BLE_GATT_BREAK_TEST_READ_ATTR_HANDLE 0x9383
+#define BLE_GATT_BREAK_TEST_WRITE_ATTR_HANDLE 0x1234
+
+static uint8_t ble_gatt_conn_test_write_value[] = { 1, 3, 64, 21, 6 };
+
+struct ble_gatt_conn_test_cb_arg {
+ uint16_t exp_conn_handle;
+ int called;
+};
+
+static int
+ble_gatt_conn_test_attr_cb(uint16_t conn_handle, uint16_t attr_handle,
+ uint8_t op, uint16_t offset, struct os_mbuf **om,
+ void *arg)
+{
+ uint8_t *buf;
+
+ switch (op) {
+ case BLE_ATT_ACCESS_OP_READ:
+ buf = os_mbuf_extend(*om, 1);
+ TEST_ASSERT_FATAL(buf != NULL);
+ *buf = 1;
+ return 0;
+
+ default:
+ return -1;
+ }
+}
+
+static int
+ble_gatt_conn_test_mtu_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ uint16_t mtu, void *arg)
+{
+ struct ble_gatt_conn_test_cb_arg *cb_arg;
+
+ cb_arg = arg;
+
+ TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
+ TEST_ASSERT(!cb_arg->called);
+ TEST_ASSERT_FATAL(error != NULL);
+ TEST_ASSERT(error->status == BLE_HS_ENOTCONN);
+ TEST_ASSERT(mtu == 0);
+
+ cb_arg->called++;
+
+ return 0;
+}
+
+static int
+ble_gatt_conn_test_disc_all_svcs_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ const struct ble_gatt_svc *service,
+ void *arg)
+{
+ struct ble_gatt_conn_test_cb_arg *cb_arg;
+
+ cb_arg = arg;
+
+ TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
+ TEST_ASSERT(!cb_arg->called);
+ TEST_ASSERT_FATAL(error != NULL);
+ TEST_ASSERT(error->status == BLE_HS_ENOTCONN);
+ TEST_ASSERT(service == NULL);
+
+ cb_arg->called++;
+
+ return 0;
+}
+
+static int
+ble_gatt_conn_test_disc_svc_uuid_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ const struct ble_gatt_svc *service,
+ void *arg)
+{
+ struct ble_gatt_conn_test_cb_arg *cb_arg;
+
+ cb_arg = arg;
+
+ TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
+ TEST_ASSERT(!cb_arg->called);
+ TEST_ASSERT_FATAL(error != NULL);
+ TEST_ASSERT(error->status == BLE_HS_ENOTCONN);
+ TEST_ASSERT(service == NULL);
+
+ cb_arg->called++;
+
+ return 0;
+}
+
+static int
+ble_gatt_conn_test_find_inc_svcs_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ const struct ble_gatt_svc *service,
+ void *arg)
+{
+ struct ble_gatt_conn_test_cb_arg *cb_arg;
+
+ cb_arg = arg;
+
+ TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
+ TEST_ASSERT(!cb_arg->called);
+ TEST_ASSERT_FATAL(error != NULL);
+ TEST_ASSERT(error->status == BLE_HS_ENOTCONN);
+ TEST_ASSERT(service == NULL);
+
+ cb_arg->called++;
+
+ return 0;
+}
+
+static int
+ble_gatt_conn_test_disc_all_chrs_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ const struct ble_gatt_chr *chr, void *arg)
+{
+ struct ble_gatt_conn_test_cb_arg *cb_arg;
+
+ cb_arg = arg;
+
+ TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
+ TEST_ASSERT(!cb_arg->called);
+ TEST_ASSERT_FATAL(error != NULL);
+ TEST_ASSERT(error->status == BLE_HS_ENOTCONN);
+ TEST_ASSERT(chr == NULL);
+
+ cb_arg->called++;
+
+ return 0;
+}
+
+static int
+ble_gatt_conn_test_disc_chr_uuid_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ const struct ble_gatt_chr *chr, void *arg)
+{
+ struct ble_gatt_conn_test_cb_arg *cb_arg;
+
+ cb_arg = arg;
+
+ TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
+ TEST_ASSERT(!cb_arg->called);
+ TEST_ASSERT_FATAL(error != NULL);
+ TEST_ASSERT(error->status == BLE_HS_ENOTCONN);
+ TEST_ASSERT(chr == NULL);
+
+ cb_arg->called++;
+
+ return 0;
+}
+
+static int
+ble_gatt_conn_test_disc_all_dscs_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ uint16_t chr_def_handle,
+ const struct ble_gatt_dsc *dsc,
+ void *arg)
+{
+ struct ble_gatt_conn_test_cb_arg *cb_arg;
+
+ cb_arg = arg;
+
+ TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
+ TEST_ASSERT(!cb_arg->called);
+ TEST_ASSERT_FATAL(error != NULL);
+ TEST_ASSERT(error->status == BLE_HS_ENOTCONN);
+ TEST_ASSERT(dsc == NULL);
+
+ cb_arg->called++;
+
+ return 0;
+}
+
+static int
+ble_gatt_conn_test_read_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ struct ble_gatt_attr *attr, void *arg)
+{
+ struct ble_gatt_conn_test_cb_arg *cb_arg;
+
+ cb_arg = arg;
+
+ TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
+ TEST_ASSERT(!cb_arg->called);
+ TEST_ASSERT_FATAL(error != NULL);
+ TEST_ASSERT(error->status == BLE_HS_ENOTCONN);
+ TEST_ASSERT(attr == NULL);
+
+ cb_arg->called++;
+
+ return 0;
+}
+
+static int
+ble_gatt_conn_test_read_uuid_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ struct ble_gatt_attr *attr, void *arg)
+{
+ struct ble_gatt_conn_test_cb_arg *cb_arg;
+
+ cb_arg = arg;
+
+ TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
+ TEST_ASSERT(!cb_arg->called);
+ TEST_ASSERT_FATAL(error != NULL);
+ TEST_ASSERT(error->status == BLE_HS_ENOTCONN);
+ TEST_ASSERT(attr == NULL);
+
+ cb_arg->called++;
+
+ return 0;
+}
+
+static int
+ble_gatt_conn_test_read_long_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ struct ble_gatt_attr *attr, void *arg)
+{
+ struct ble_gatt_conn_test_cb_arg *cb_arg;
+
+ cb_arg = arg;
+
+ TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
+ TEST_ASSERT(!cb_arg->called);
+ TEST_ASSERT_FATAL(error != NULL);
+ TEST_ASSERT(error->status == BLE_HS_ENOTCONN);
+ TEST_ASSERT(attr == NULL);
+
+ cb_arg->called++;
+
+ return 0;
+}
+static int
+ble_gatt_conn_test_read_mult_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ struct ble_gatt_attr *attr, void *arg)
+{
+ struct ble_gatt_conn_test_cb_arg *cb_arg;
+
+ cb_arg = arg;
+
+ TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
+ TEST_ASSERT(!cb_arg->called);
+ TEST_ASSERT_FATAL(error != NULL);
+ TEST_ASSERT(error->status == BLE_HS_ENOTCONN);
+ TEST_ASSERT(attr->om == NULL);
+
+ cb_arg->called++;
+
+ return 0;
+}
+
+static int
+ble_gatt_conn_test_write_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ struct ble_gatt_attr *attr,
+ void *arg)
+{
+ struct ble_gatt_conn_test_cb_arg *cb_arg;
+
+ cb_arg = arg;
+
+ TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
+ TEST_ASSERT(!cb_arg->called);
+ TEST_ASSERT_FATAL(error != NULL);
+ TEST_ASSERT(error->status == BLE_HS_ENOTCONN);
+ TEST_ASSERT(attr != NULL);
+ TEST_ASSERT(attr->handle == BLE_GATT_BREAK_TEST_WRITE_ATTR_HANDLE);
+
+ cb_arg->called++;
+
+ return 0;
+}
+
+static int
+ble_gatt_conn_test_write_long_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ struct ble_gatt_attr *attr, void *arg)
+{
+ struct ble_gatt_conn_test_cb_arg *cb_arg;
+
+ cb_arg = arg;
+
+ TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
+ TEST_ASSERT(!cb_arg->called);
+ TEST_ASSERT_FATAL(error != NULL);
+ TEST_ASSERT(error->status == BLE_HS_ENOTCONN);
+ TEST_ASSERT(attr != NULL);
+ TEST_ASSERT(attr->handle == BLE_GATT_BREAK_TEST_WRITE_ATTR_HANDLE);
+
+ cb_arg->called++;
+
+ return 0;
+}
+
+static int
+ble_gatt_conn_test_write_rel_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ struct ble_gatt_attr *attrs,
+ uint8_t num_attrs,
+ void *arg)
+{
+ struct ble_gatt_conn_test_cb_arg *cb_arg;
+
+ cb_arg = arg;
+
+ TEST_ASSERT(cb_arg->exp_conn_handle == conn_handle);
+ TEST_ASSERT(!cb_arg->called);
+ TEST_ASSERT_FATAL(error != NULL);
+ TEST_ASSERT(error->status == BLE_HS_ENOTCONN);
+ TEST_ASSERT(attrs != NULL);
+
+ cb_arg->called++;
+
+ return 0;
+}
+
+TEST_CASE(ble_gatt_conn_test_disconnect)
+{
+ struct ble_gatt_conn_test_cb_arg mtu_arg = { 0 };
+ struct ble_gatt_conn_test_cb_arg disc_all_svcs_arg = { 0 };
+ struct ble_gatt_conn_test_cb_arg disc_svc_uuid_arg = { 0 };
+ struct ble_gatt_conn_test_cb_arg find_inc_svcs_arg = { 0 };
+ struct ble_gatt_conn_test_cb_arg disc_all_chrs_arg = { 0 };
+ struct ble_gatt_conn_test_cb_arg disc_chr_uuid_arg = { 0 };
+ struct ble_gatt_conn_test_cb_arg disc_all_dscs_arg = { 0 };
+ struct ble_gatt_conn_test_cb_arg read_arg = { 0 };
+ struct ble_gatt_conn_test_cb_arg read_uuid_arg = { 0 };
+ struct ble_gatt_conn_test_cb_arg read_long_arg = { 0 };
+ struct ble_gatt_conn_test_cb_arg read_mult_arg = { 0 };
+ struct ble_gatt_conn_test_cb_arg write_arg = { 0 };
+ struct ble_gatt_conn_test_cb_arg write_long_arg = { 0 };
+ struct ble_gatt_conn_test_cb_arg write_rel_arg = { 0 };
+ struct ble_gatt_attr attr;
+ uint16_t attr_handle;
+ int rc;
+
+ ble_hs_test_util_init();
+
+ /*** Register an attribute to allow indicatations to be sent. */
+ rc = ble_att_svr_register(BLE_UUID16(0x1212), BLE_ATT_F_READ,
+ &attr_handle,
+ ble_gatt_conn_test_attr_cb, NULL);
+ TEST_ASSERT(rc == 0);
+
+ /* Create three connections. */
+ ble_hs_test_util_create_conn(1, ((uint8_t[]){1,2,3,4,5,6,7,8}),
+ NULL, NULL);
+ ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+ NULL, NULL);
+ ble_hs_test_util_create_conn(3, ((uint8_t[]){3,4,5,6,7,8,9,10}),
+ NULL, NULL);
+
+ /*** Schedule some GATT procedures. */
+ /* Connection 1. */
+ mtu_arg.exp_conn_handle = 1;
+ ble_gattc_exchange_mtu(1, ble_gatt_conn_test_mtu_cb, &mtu_arg);
+
+ disc_all_svcs_arg.exp_conn_handle = 1;
+ rc = ble_gattc_disc_all_svcs(1, ble_gatt_conn_test_disc_all_svcs_cb,
+ &disc_all_svcs_arg);
+ TEST_ASSERT_FATAL(rc == 0);
+
+ disc_svc_uuid_arg.exp_conn_handle = 1;
+ rc = ble_gattc_disc_svc_by_uuid(1, BLE_UUID16(0x1111),
+ ble_gatt_conn_test_disc_svc_uuid_cb,
+ &disc_svc_uuid_arg);
+ TEST_ASSERT_FATAL(rc == 0);
+
+ find_inc_svcs_arg.exp_conn_handle = 1;
+ rc = ble_gattc_find_inc_svcs(1, 1, 0xffff,
+ ble_gatt_conn_test_find_inc_svcs_cb,
+ &find_inc_svcs_arg);
+ TEST_ASSERT_FATAL(rc == 0);
+
+ disc_all_chrs_arg.exp_conn_handle = 1;
+ rc = ble_gattc_disc_all_chrs(1, 1, 0xffff,
+ ble_gatt_conn_test_disc_all_chrs_cb,
+ &disc_all_chrs_arg);
+ TEST_ASSERT_FATAL(rc == 0);
+
+ /* Connection 2. */
+ disc_all_dscs_arg.exp_conn_handle = 2;
+ rc = ble_gattc_disc_all_dscs(2, 3, 0xffff,
+ ble_gatt_conn_test_disc_all_dscs_cb,
+ &disc_all_dscs_arg);
+
+ disc_chr_uuid_arg.exp_conn_handle = 2;
+ rc = ble_gattc_disc_chrs_by_uuid(2, 2, 0xffff, BLE_UUID16(0x2222),
+ ble_gatt_conn_test_disc_chr_uuid_cb,
+ &disc_chr_uuid_arg);
+
+ read_arg.exp_conn_handle = 2;
+ rc = ble_gattc_read(2, BLE_GATT_BREAK_TEST_READ_ATTR_HANDLE,
+ ble_gatt_conn_test_read_cb, &read_arg);
+ TEST_ASSERT_FATAL(rc == 0);
+
+ read_uuid_arg.exp_conn_handle = 2;
+ rc = ble_gattc_read_by_uuid(2, 1, 0xffff, BLE_UUID16(0x3333),
+ ble_gatt_conn_test_read_uuid_cb,
+ &read_uuid_arg);
+ TEST_ASSERT_FATAL(rc == 0);
+
+ read_long_arg.exp_conn_handle = 2;
+ rc = ble_gattc_read_long(2, BLE_GATT_BREAK_TEST_READ_ATTR_HANDLE,
+ ble_gatt_conn_test_read_long_cb, &read_long_arg);
+ TEST_ASSERT_FATAL(rc == 0);
+
+ /* Connection 3. */
+ read_mult_arg.exp_conn_handle = 3;
+ rc = ble_gattc_read_mult(3, ((uint16_t[3]){5,6,7}), 3,
+ ble_gatt_conn_test_read_mult_cb, &read_mult_arg);
+ TEST_ASSERT_FATAL(rc == 0);
+
+ write_arg.exp_conn_handle = 3;
+ rc = ble_hs_test_util_gatt_write_flat(
+ 3, BLE_GATT_BREAK_TEST_WRITE_ATTR_HANDLE,
+ ble_gatt_conn_test_write_value, sizeof ble_gatt_conn_test_write_value,
+ ble_gatt_conn_test_write_cb, &write_arg);
+ TEST_ASSERT_FATAL(rc == 0);
+
+ write_long_arg.exp_conn_handle = 3;
+ rc = ble_hs_test_util_gatt_write_long_flat(
+ 3, BLE_GATT_BREAK_TEST_WRITE_ATTR_HANDLE,
+ ble_gatt_conn_test_write_value, sizeof ble_gatt_conn_test_write_value,
+ ble_gatt_conn_test_write_long_cb, &write_long_arg);
+ TEST_ASSERT_FATAL(rc == 0);
+
+ attr.handle = 8;
+ attr.offset = 0;
+ attr.om = os_msys_get_pkthdr(0, 0);
+ write_rel_arg.exp_conn_handle = 3;
+ rc = ble_gattc_write_reliable(
+ 3, &attr, 1, ble_gatt_conn_test_write_rel_cb, &write_rel_arg);
+ TEST_ASSERT_FATAL(rc == 0);
+
+ /*** Start the procedures. */
+ ble_hs_test_util_tx_all();
+
+ /*** Break the connections; verify proper callbacks got called. */
+ /* Connection 1. */
+ ble_gattc_connection_broken(1);
+ TEST_ASSERT(mtu_arg.called == 1);
+ TEST_ASSERT(disc_all_svcs_arg.called == 1);
+ TEST_ASSERT(disc_svc_uuid_arg.called == 1);
+ TEST_ASSERT(find_inc_svcs_arg.called == 1);
+ TEST_ASSERT(disc_all_chrs_arg.called == 1);
+ TEST_ASSERT(disc_chr_uuid_arg.called == 0);
+ TEST_ASSERT(disc_all_dscs_arg.called == 0);
+ TEST_ASSERT(read_arg.called == 0);
+ TEST_ASSERT(read_uuid_arg.called == 0);
+ TEST_ASSERT(read_long_arg.called == 0);
+ TEST_ASSERT(read_mult_arg.called == 0);
+ TEST_ASSERT(write_arg.called == 0);
+ TEST_ASSERT(write_long_arg.called == 0);
+ TEST_ASSERT(write_rel_arg.called == 0);
+
+ /* Connection 2. */
+ ble_gattc_connection_broken(2);
+ TEST_ASSERT(mtu_arg.called == 1);
+ TEST_ASSERT(disc_all_svcs_arg.called == 1);
+ TEST_ASSERT(disc_svc_uuid_arg.called == 1);
+ TEST_ASSERT(find_inc_svcs_arg.called == 1);
+ TEST_ASSERT(disc_all_chrs_arg.called == 1);
+ TEST_ASSERT(disc_chr_uuid_arg.called == 1);
+ TEST_ASSERT(disc_all_dscs_arg.called == 1);
+ TEST_ASSERT(read_arg.called == 1);
+ TEST_ASSERT(read_uuid_arg.called == 1);
+ TEST_ASSERT(read_long_arg.called == 1);
+ TEST_ASSERT(read_mult_arg.called == 0);
+ TEST_ASSERT(write_arg.called == 0);
+ TEST_ASSERT(write_long_arg.called == 0);
+ TEST_ASSERT(write_rel_arg.called == 0);
+
+ /* Connection 3. */
+ ble_gattc_connection_broken(3);
+ TEST_ASSERT(mtu_arg.called == 1);
+ TEST_ASSERT(disc_all_svcs_arg.called == 1);
+ TEST_ASSERT(disc_svc_uuid_arg.called == 1);
+ TEST_ASSERT(find_inc_svcs_arg.called == 1);
+ TEST_ASSERT(disc_all_chrs_arg.called == 1);
+ TEST_ASSERT(disc_chr_uuid_arg.called == 1);
+ TEST_ASSERT(disc_all_dscs_arg.called == 1);
+ TEST_ASSERT(read_arg.called == 1);
+ TEST_ASSERT(read_uuid_arg.called == 1);
+ TEST_ASSERT(read_long_arg.called == 1);
+ TEST_ASSERT(read_mult_arg.called == 1);
+ TEST_ASSERT(write_arg.called == 1);
+ TEST_ASSERT(write_long_arg.called == 1);
+ TEST_ASSERT(write_rel_arg.called == 1);
+}
+
+TEST_SUITE(ble_gatt_break_suite)
+{
+ tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
+
+ ble_gatt_conn_test_disconnect();
+}
+
+int
+ble_gatt_conn_test_all(void)
+{
+ ble_gatt_break_suite();
+
+ return tu_any_failed;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/net/nimble/host/test/src/ble_gatt_disc_c_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_gatt_disc_c_test.c b/net/nimble/host/test/src/ble_gatt_disc_c_test.c
new file mode 100644
index 0000000..a4eb67b
--- /dev/null
+++ b/net/nimble/host/test/src/ble_gatt_disc_c_test.c
@@ -0,0 +1,547 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 <string.h>
+#include <errno.h>
+#include <limits.h>
+#include "testutil/testutil.h"
+#include "nimble/ble.h"
+#include "host/ble_hs_test.h"
+#include "host/ble_gatt.h"
+#include "host/ble_uuid.h"
+#include "ble_hs_test_util.h"
+
+struct ble_gatt_disc_c_test_char {
+ uint16_t def_handle;
+ uint16_t val_handle;
+ uint16_t uuid16; /* 0 if not present. */
+ uint8_t properties;
+ uint8_t uuid128[16];
+};
+
+#define BLE_GATT_DISC_C_TEST_MAX_CHARS 256
+static struct ble_gatt_chr
+ ble_gatt_disc_c_test_chars[BLE_GATT_DISC_C_TEST_MAX_CHARS];
+static int ble_gatt_disc_c_test_num_chars;
+static int ble_gatt_disc_c_test_rx_complete;
+
+static void
+ble_gatt_disc_c_test_init(void)
+{
+ ble_hs_test_util_init();
+
+ ble_gatt_disc_c_test_num_chars = 0;
+ ble_gatt_disc_c_test_rx_complete = 0;
+}
+
+static int
+ble_gatt_disc_c_test_misc_rx_rsp_once(
+ uint16_t conn_handle, struct ble_gatt_disc_c_test_char *chars)
+{
+ struct ble_att_read_type_rsp rsp;
+ uint8_t buf[1024];
+ int off;
+ int rc;
+ int i;
+
+ /* Send the pending ATT Read By Type Request. */
+ ble_hs_test_util_tx_all();
+
+ if (chars[0].uuid16 != 0) {
+ rsp.batp_length = BLE_ATT_READ_TYPE_ADATA_BASE_SZ +
+ BLE_GATT_CHR_DECL_SZ_16;
+ } else {
+ rsp.batp_length = BLE_ATT_READ_TYPE_ADATA_BASE_SZ +
+ BLE_GATT_CHR_DECL_SZ_128;
+ }
+
+ ble_att_read_type_rsp_write(buf, BLE_ATT_READ_TYPE_RSP_BASE_SZ, &rsp);
+
+ off = BLE_ATT_READ_TYPE_RSP_BASE_SZ;
+ for (i = 0; ; i++) {
+ if (chars[i].def_handle == 0) {
+ /* No more services. */
+ break;
+ }
+
+ /* If the value length is changing, we need a separate response. */
+ if (((chars[i].uuid16 == 0) ^ (chars[0].uuid16 == 0)) != 0) {
+ break;
+ }
+
+ htole16(buf + off, chars[i].def_handle);
+ off += 2;
+
+ buf[off] = chars[i].properties;
+ off++;
+
+ htole16(buf + off, chars[i].val_handle);
+ off += 2;
+
+ if (chars[i].uuid16 != 0) {
+ htole16(buf + off, chars[i].uuid16);
+ off += 2;
+ } else {
+ memcpy(buf + off, chars[i].uuid128, 16);
+ off += 16;
+ }
+ }
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+ buf, off);
+ TEST_ASSERT(rc == 0);
+
+ return i;
+}
+
+static void
+ble_gatt_disc_c_test_misc_rx_rsp(uint16_t conn_handle,
+ uint16_t end_handle,
+ struct ble_gatt_disc_c_test_char *chars)
+{
+ int count;
+ int idx;
+
+ idx = 0;
+ while (chars[idx].def_handle != 0) {
+ count = ble_gatt_disc_c_test_misc_rx_rsp_once(conn_handle,
+ chars + idx);
+ if (count == 0) {
+ break;
+ }
+ idx += count;
+ }
+
+ if (chars[idx - 1].def_handle != end_handle) {
+ /* Send the pending ATT Request. */
+ ble_hs_test_util_tx_all();
+ ble_hs_test_util_rx_att_err_rsp(conn_handle, BLE_ATT_OP_READ_TYPE_REQ,
+ BLE_ATT_ERR_ATTR_NOT_FOUND,
+ chars[idx - 1].def_handle);
+ }
+}
+
+static void
+ble_gatt_disc_c_test_misc_verify_chars(struct ble_gatt_disc_c_test_char *chars,
+ int stop_after)
+{
+ uint16_t uuid16;
+ int i;
+
+ if (stop_after == 0) {
+ stop_after = INT_MAX;
+ }
+
+ for (i = 0; i < stop_after && chars[i].def_handle != 0; i++) {
+ TEST_ASSERT(chars[i].def_handle ==
+ ble_gatt_disc_c_test_chars[i].def_handle);
+ TEST_ASSERT(chars[i].val_handle ==
+ ble_gatt_disc_c_test_chars[i].val_handle);
+ if (chars[i].uuid16 != 0) {
+ uuid16 = ble_uuid_128_to_16(ble_gatt_disc_c_test_chars[i].uuid128);
+ TEST_ASSERT(chars[i].uuid16 == uuid16);
+ } else {
+ TEST_ASSERT(memcmp(chars[i].uuid128,
+ ble_gatt_disc_c_test_chars[i].uuid128,
+ 16) == 0);
+ }
+ }
+
+ TEST_ASSERT(i == ble_gatt_disc_c_test_num_chars);
+ TEST_ASSERT(ble_gatt_disc_c_test_rx_complete);
+}
+
+static int
+ble_gatt_disc_c_test_misc_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ const struct ble_gatt_chr *chr, void *arg)
+{
+ struct ble_gatt_chr *dst;
+ int *stop_after;
+
+ TEST_ASSERT(error != NULL);
+ TEST_ASSERT(!ble_gatt_disc_c_test_rx_complete);
+
+ stop_after = arg;
+
+ switch (error->status) {
+ case 0:
+ TEST_ASSERT_FATAL(ble_gatt_disc_c_test_num_chars <
+ BLE_GATT_DISC_C_TEST_MAX_CHARS);
+
+ dst = ble_gatt_disc_c_test_chars + ble_gatt_disc_c_test_num_chars++;
+ *dst = *chr;
+ break;
+
+ case BLE_HS_EDONE:
+ ble_gatt_disc_c_test_rx_complete = 1;
+ break;
+
+ default:
+ TEST_ASSERT(0);
+ break;
+ }
+
+ if (*stop_after > 0) {
+ (*stop_after)--;
+ if (*stop_after == 0) {
+ ble_gatt_disc_c_test_rx_complete = 1;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static void
+ble_gatt_disc_c_test_misc_all(uint16_t start_handle, uint16_t end_handle,
+ int stop_after,
+ struct ble_gatt_disc_c_test_char *chars)
+{
+ int num_left;
+ int rc;
+
+ ble_gatt_disc_c_test_init();
+
+ ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+ NULL, NULL);
+
+ num_left = stop_after;
+ rc = ble_gattc_disc_all_chrs(2, start_handle, end_handle,
+ ble_gatt_disc_c_test_misc_cb, &num_left);
+ TEST_ASSERT(rc == 0);
+
+ ble_gatt_disc_c_test_misc_rx_rsp(2, end_handle, chars);
+ ble_gatt_disc_c_test_misc_verify_chars(chars, stop_after);
+}
+
+static void
+ble_gatt_disc_c_test_misc_uuid(uint16_t start_handle, uint16_t end_handle,
+ int stop_after, uint8_t *uuid128,
+ struct ble_gatt_disc_c_test_char *rsp_chars,
+ struct ble_gatt_disc_c_test_char *ret_chars)
+{
+ int rc;
+
+ ble_gatt_disc_c_test_init();
+
+ ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+ NULL, NULL);
+
+ rc = ble_gattc_disc_chrs_by_uuid(2, start_handle, end_handle,
+ uuid128,
+ ble_gatt_disc_c_test_misc_cb,
+ &stop_after);
+ TEST_ASSERT(rc == 0);
+
+ ble_gatt_disc_c_test_misc_rx_rsp(2, end_handle, rsp_chars);
+ ble_gatt_disc_c_test_misc_verify_chars(ret_chars, 0);
+}
+
+TEST_CASE(ble_gatt_disc_c_test_disc_all)
+{
+ /*** One 16-bit characteristic. */
+ ble_gatt_disc_c_test_misc_all(50, 100, 0,
+ (struct ble_gatt_disc_c_test_char[]) {
+ {
+ .def_handle = 55,
+ .val_handle = 56,
+ .uuid16 = 0x2010,
+ }, { 0 }
+ });
+
+ /*** Two 16-bit characteristics. */
+ ble_gatt_disc_c_test_misc_all(50, 100, 0,
+ (struct ble_gatt_disc_c_test_char[]) {
+ {
+ .def_handle = 55,
+ .val_handle = 56,
+ .uuid16 = 0x2010,
+ }, {
+ .def_handle = 57,
+ .val_handle = 58,
+ .uuid16 = 0x64ba,
+ }, { 0 }
+ });
+
+ /*** Five 16-bit characteristics. */
+ ble_gatt_disc_c_test_misc_all(50, 100, 0,
+ (struct ble_gatt_disc_c_test_char[]) {
+ {
+ .def_handle = 55,
+ .val_handle = 56,
+ .uuid16 = 0x2010,
+ }, {
+ .def_handle = 57,
+ .val_handle = 58,
+ .uuid16 = 0x64ba,
+ }, {
+ .def_handle = 59,
+ .val_handle = 60,
+ .uuid16 = 0x5372,
+ }, {
+ .def_handle = 61,
+ .val_handle = 62,
+ .uuid16 = 0xab93,
+ }, {
+ .def_handle = 63,
+ .val_handle = 64,
+ .uuid16 = 0x0023,
+ }, { 0 }
+ });
+
+ /*** Interleaved 16-bit and 128-bit characteristics. */
+ ble_gatt_disc_c_test_misc_all(50, 100, 0,
+ (struct ble_gatt_disc_c_test_char[]) {
+ {
+ .def_handle = 83,
+ .val_handle = 84,
+ .uuid16 = 0x2010,
+ }, {
+ .def_handle = 87,
+ .val_handle = 88,
+ .uuid128 = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 },
+ }, {
+ .def_handle = 91,
+ .val_handle = 92,
+ .uuid16 = 0x0003,
+ }, {
+ .def_handle = 93,
+ .val_handle = 94,
+ .uuid128 = { 1,0,4,0,6,9,17,7,8,43,7,4,12,43,19,35 },
+ }, {
+ .def_handle = 98,
+ .val_handle = 99,
+ .uuid16 = 0xabfa,
+ }, { 0 }
+ });
+
+ /*** Ends with final handle ID. */
+ ble_gatt_disc_c_test_misc_all(50, 100, 0,
+ (struct ble_gatt_disc_c_test_char[]) {
+ {
+ .def_handle = 55,
+ .val_handle = 56,
+ .uuid16 = 0x2010,
+ }, {
+ .def_handle = 99,
+ .val_handle = 100,
+ .uuid16 = 0x64ba,
+ }, { 0 }
+ });
+
+ /*** Stop after two characteristics. */
+ ble_gatt_disc_c_test_misc_all(50, 100, 2,
+ (struct ble_gatt_disc_c_test_char[]) {
+ {
+ .def_handle = 55,
+ .val_handle = 56,
+ .uuid16 = 0x2010,
+ }, {
+ .def_handle = 57,
+ .val_handle = 58,
+ .uuid16 = 0x64ba,
+ }, {
+ .def_handle = 59,
+ .val_handle = 60,
+ .uuid16 = 0x5372,
+ }, {
+ .def_handle = 61,
+ .val_handle = 62,
+ .uuid16 = 0xab93,
+ }, {
+ .def_handle = 63,
+ .val_handle = 64,
+ .uuid16 = 0x0023,
+ }, { 0 }
+ });
+}
+
+TEST_CASE(ble_gatt_disc_c_test_disc_uuid)
+{
+ /*** One 16-bit characteristic. */
+ ble_gatt_disc_c_test_misc_uuid(50, 100, 0, BLE_UUID16(0x2010),
+ (struct ble_gatt_disc_c_test_char[]) {
+ {
+ .def_handle = 55,
+ .val_handle = 56,
+ .uuid16 = 0x2010,
+ }, { 0 } },
+ (struct ble_gatt_disc_c_test_char[]) {
+ {
+ .def_handle = 55,
+ .val_handle = 56,
+ .uuid16 = 0x2010,
+ }, { 0 } }
+ );
+
+ /*** No matching characteristics. */
+ ble_gatt_disc_c_test_misc_uuid(50, 100, 0, BLE_UUID16(0x2010),
+ (struct ble_gatt_disc_c_test_char[]) {
+ {
+ .def_handle = 55,
+ .val_handle = 56,
+ .uuid16 = 0x1234,
+ }, { 0 } },
+ (struct ble_gatt_disc_c_test_char[]) {
+ { 0 } }
+ );
+
+ /*** 2/5 16-bit characteristics. */
+ ble_gatt_disc_c_test_misc_uuid(50, 100, 0, BLE_UUID16(0x2010),
+ (struct ble_gatt_disc_c_test_char[]) {
+ {
+ .def_handle = 55,
+ .val_handle = 56,
+ .uuid16 = 0x2010,
+ }, {
+ .def_handle = 57,
+ .val_handle = 58,
+ .uuid16 = 0x64ba,
+ }, {
+ .def_handle = 59,
+ .val_handle = 60,
+ .uuid16 = 0x5372,
+ }, {
+ .def_handle = 61,
+ .val_handle = 62,
+ .uuid16 = 0x2010,
+ }, {
+ .def_handle = 63,
+ .val_handle = 64,
+ .uuid16 = 0x0023,
+ }, { 0 } },
+ (struct ble_gatt_disc_c_test_char[]) {
+ {
+ .def_handle = 55,
+ .val_handle = 56,
+ .uuid16 = 0x2010,
+ }, {
+ .def_handle = 61,
+ .val_handle = 62,
+ .uuid16 = 0x2010,
+ }, { 0 } }
+ );
+
+ /*** Interleaved 16-bit and 128-bit characteristics. */
+ ble_gatt_disc_c_test_misc_uuid(
+ 50, 100, 0,
+ ((uint8_t[]){ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 }),
+ (struct ble_gatt_disc_c_test_char[]) {
+ {
+ .def_handle = 83,
+ .val_handle = 84,
+ .uuid16 = 0x2010,
+ }, {
+ .def_handle = 87,
+ .val_handle = 88,
+ .uuid128 = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 },
+ }, {
+ .def_handle = 91,
+ .val_handle = 92,
+ .uuid16 = 0x0003,
+ }, {
+ .def_handle = 93,
+ .val_handle = 94,
+ .uuid128 = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 },
+ }, {
+ .def_handle = 98,
+ .val_handle = 99,
+ .uuid16 = 0xabfa,
+ }, { 0 } },
+ (struct ble_gatt_disc_c_test_char[]) {
+ {
+ .def_handle = 87,
+ .val_handle = 88,
+ .uuid128 = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 },
+ }, {
+ .def_handle = 93,
+ .val_handle = 94,
+ .uuid128 = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 },
+ }, { 0 } }
+ );
+
+ /*** Ends with final handle ID. */
+ ble_gatt_disc_c_test_misc_uuid(50, 100, 0, BLE_UUID16(0x64ba),
+ (struct ble_gatt_disc_c_test_char[]) {
+ {
+ .def_handle = 55,
+ .val_handle = 56,
+ .uuid16 = 0x2010,
+ }, {
+ .def_handle = 99,
+ .val_handle = 100,
+ .uuid16 = 0x64ba,
+ }, { 0 } },
+ (struct ble_gatt_disc_c_test_char[]) {
+ {
+ .def_handle = 99,
+ .val_handle = 100,
+ .uuid16 = 0x64ba,
+ }, { 0 } }
+ );
+
+ /*** Stop after first characteristic. */
+ ble_gatt_disc_c_test_misc_uuid(50, 100, 1, BLE_UUID16(0x2010),
+ (struct ble_gatt_disc_c_test_char[]) {
+ {
+ .def_handle = 55,
+ .val_handle = 56,
+ .uuid16 = 0x2010,
+ }, {
+ .def_handle = 57,
+ .val_handle = 58,
+ .uuid16 = 0x64ba,
+ }, {
+ .def_handle = 59,
+ .val_handle = 60,
+ .uuid16 = 0x5372,
+ }, {
+ .def_handle = 61,
+ .val_handle = 62,
+ .uuid16 = 0x2010,
+ }, {
+ .def_handle = 63,
+ .val_handle = 64,
+ .uuid16 = 0x0023,
+ }, { 0 } },
+ (struct ble_gatt_disc_c_test_char[]) {
+ {
+ .def_handle = 55,
+ .val_handle = 56,
+ .uuid16 = 0x2010,
+ }, { 0 } }
+ );
+}
+
+TEST_SUITE(ble_gatt_disc_c_test_suite)
+{
+ tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
+
+ ble_gatt_disc_c_test_disc_all();
+ ble_gatt_disc_c_test_disc_uuid();
+}
+
+int
+ble_gatt_disc_c_test_all(void)
+{
+ ble_gatt_disc_c_test_suite();
+
+ return tu_any_failed;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/net/nimble/host/test/src/ble_gatt_disc_d_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_gatt_disc_d_test.c b/net/nimble/host/test/src/ble_gatt_disc_d_test.c
new file mode 100644
index 0000000..7e021e2
--- /dev/null
+++ b/net/nimble/host/test/src/ble_gatt_disc_d_test.c
@@ -0,0 +1,363 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 <string.h>
+#include <errno.h>
+#include <limits.h>
+#include "testutil/testutil.h"
+#include "nimble/ble.h"
+#include "host/ble_hs_test.h"
+#include "host/ble_gatt.h"
+#include "host/ble_uuid.h"
+#include "ble_hs_test_util.h"
+
+struct ble_gatt_disc_d_test_dsc {
+ uint16_t chr_val_handle; /* 0 if last entry. */
+ uint16_t dsc_handle;
+ uint8_t dsc_uuid128[16];
+};
+
+#define BLE_GATT_DISC_D_TEST_MAX_DSCS 256
+static struct ble_gatt_disc_d_test_dsc
+ ble_gatt_disc_d_test_dscs[BLE_GATT_DISC_D_TEST_MAX_DSCS];
+static int ble_gatt_disc_d_test_num_dscs;
+static int ble_gatt_disc_d_test_rx_complete;
+
+static void
+ble_gatt_disc_d_test_init(void)
+{
+ ble_hs_test_util_init();
+
+ ble_gatt_disc_d_test_num_dscs = 0;
+ ble_gatt_disc_d_test_rx_complete = 0;
+}
+
+static int
+ble_gatt_disc_d_test_misc_rx_rsp_once(
+ uint16_t conn_handle, struct ble_gatt_disc_d_test_dsc *dscs)
+{
+ struct ble_att_find_info_rsp rsp;
+ uint8_t buf[1024];
+ uint16_t uuid16_cur;
+ uint16_t uuid16_0;
+ int off;
+ int rc;
+ int i;
+
+ /* Send the pending ATT Read By Type Request. */
+ ble_hs_test_util_tx_all();
+
+ uuid16_0 = ble_uuid_128_to_16(dscs[0].dsc_uuid128);
+ if (uuid16_0 != 0) {
+ rsp.bafp_format = BLE_ATT_FIND_INFO_RSP_FORMAT_16BIT;
+ } else {
+ rsp.bafp_format = BLE_ATT_FIND_INFO_RSP_FORMAT_128BIT;
+ }
+
+ ble_att_find_info_rsp_write(buf, BLE_ATT_FIND_INFO_RSP_BASE_SZ, &rsp);
+
+ off = BLE_ATT_FIND_INFO_RSP_BASE_SZ;
+ for (i = 0; ; i++) {
+ if (dscs[i].chr_val_handle == 0) {
+ /* No more descriptors. */
+ break;
+ }
+
+ /* If the value length is changing, we need a separate response. */
+ uuid16_cur = ble_uuid_128_to_16(dscs[i].dsc_uuid128);
+ if (((uuid16_0 == 0) ^ (uuid16_cur == 0)) != 0) {
+ break;
+ }
+
+ htole16(buf + off, dscs[i].dsc_handle);
+ off += 2;
+
+ if (uuid16_cur != 0) {
+ htole16(buf + off, uuid16_cur);
+ off += 2;
+ } else {
+ memcpy(buf + off, dscs[i].dsc_uuid128, 16);
+ off += 16;
+ }
+ }
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+ buf, off);
+ TEST_ASSERT(rc == 0);
+
+ return i;
+}
+
+static void
+ble_gatt_disc_d_test_misc_rx_rsp(uint16_t conn_handle,
+ uint16_t end_handle,
+ struct ble_gatt_disc_d_test_dsc *dscs)
+{
+ int count;
+ int idx;
+
+ idx = 0;
+ while (dscs[idx].chr_val_handle != 0) {
+ count = ble_gatt_disc_d_test_misc_rx_rsp_once(conn_handle, dscs + idx);
+ if (count == 0) {
+ break;
+ }
+ idx += count;
+ }
+
+ if (dscs[idx - 1].dsc_handle != end_handle) {
+ /* Send the pending ATT Request. */
+ ble_hs_test_util_tx_all();
+ ble_hs_test_util_rx_att_err_rsp(conn_handle, BLE_ATT_OP_FIND_INFO_REQ,
+ BLE_ATT_ERR_ATTR_NOT_FOUND,
+ end_handle);
+ }
+}
+
+static void
+ble_gatt_disc_d_test_misc_verify_dscs(struct ble_gatt_disc_d_test_dsc *dscs,
+ int stop_after)
+{
+ int i;
+
+ if (stop_after == 0) {
+ stop_after = INT_MAX;
+ }
+
+ for (i = 0; i < stop_after && dscs[i].chr_val_handle != 0; i++) {
+ TEST_ASSERT(dscs[i].chr_val_handle ==
+ ble_gatt_disc_d_test_dscs[i].chr_val_handle);
+ TEST_ASSERT(dscs[i].dsc_handle ==
+ ble_gatt_disc_d_test_dscs[i].dsc_handle);
+ TEST_ASSERT(memcmp(dscs[i].dsc_uuid128,
+ ble_gatt_disc_d_test_dscs[i].dsc_uuid128,
+ 16) == 0);
+ }
+
+ TEST_ASSERT(i == ble_gatt_disc_d_test_num_dscs);
+ TEST_ASSERT(ble_gatt_disc_d_test_rx_complete);
+}
+
+static int
+ble_gatt_disc_d_test_misc_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ uint16_t chr_val_handle,
+ const struct ble_gatt_dsc *dsc,
+ void *arg)
+{
+ struct ble_gatt_disc_d_test_dsc *dst;
+ int *stop_after;
+
+ TEST_ASSERT(error != NULL);
+ TEST_ASSERT(!ble_gatt_disc_d_test_rx_complete);
+
+ stop_after = arg;
+
+ switch (error->status) {
+ case 0:
+ TEST_ASSERT_FATAL(ble_gatt_disc_d_test_num_dscs <
+ BLE_GATT_DISC_D_TEST_MAX_DSCS);
+
+ dst = ble_gatt_disc_d_test_dscs + ble_gatt_disc_d_test_num_dscs++;
+ dst->chr_val_handle = chr_val_handle;
+ dst->dsc_handle = dsc->handle;
+ memcpy(dst->dsc_uuid128, dsc->uuid128, 16);
+ break;
+
+ case BLE_HS_EDONE:
+ ble_gatt_disc_d_test_rx_complete = 1;
+ break;
+
+ default:
+ TEST_ASSERT(0);
+ break;
+ }
+
+ if (*stop_after > 0) {
+ (*stop_after)--;
+ if (*stop_after == 0) {
+ ble_gatt_disc_d_test_rx_complete = 1;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static void
+ble_gatt_disc_d_test_misc_all(uint16_t chr_val_handle, uint16_t end_handle,
+ int stop_after,
+ struct ble_gatt_disc_d_test_dsc *dscs)
+{
+ int num_left;
+ int rc;
+
+ ble_gatt_disc_d_test_init();
+
+ ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+ NULL, NULL);
+
+ num_left = stop_after;
+ rc = ble_gattc_disc_all_dscs(2, chr_val_handle, end_handle,
+ ble_gatt_disc_d_test_misc_cb, &num_left);
+ TEST_ASSERT(rc == 0);
+
+ ble_gatt_disc_d_test_misc_rx_rsp(2, end_handle, dscs);
+ ble_gatt_disc_d_test_misc_verify_dscs(dscs, stop_after);
+}
+
+TEST_CASE(ble_gatt_disc_d_test_1)
+{
+ /*** One 16-bit descriptor. */
+ ble_gatt_disc_d_test_misc_all(5, 10, 0,
+ ((struct ble_gatt_disc_d_test_dsc[]) { {
+ .chr_val_handle = 5,
+ .dsc_handle = 6,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x1234),
+ }, {
+ 0
+ } })
+ );
+
+ /*** Two 16-bit descriptors. */
+ ble_gatt_disc_d_test_misc_all(50, 100, 0,
+ ((struct ble_gatt_disc_d_test_dsc[]) { {
+ .chr_val_handle = 50,
+ .dsc_handle = 51,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x1111),
+ }, {
+ .chr_val_handle = 50,
+ .dsc_handle = 52,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x2222),
+ }, {
+ 0
+ } })
+ );
+
+ /*** Five 16-bit descriptors. */
+ ble_gatt_disc_d_test_misc_all(50, 100, 0,
+ ((struct ble_gatt_disc_d_test_dsc[]) { {
+ .chr_val_handle = 50,
+ .dsc_handle = 51,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x1111),
+ }, {
+ .chr_val_handle = 50,
+ .dsc_handle = 52,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x2222),
+ }, {
+ .chr_val_handle = 50,
+ .dsc_handle = 53,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x3333),
+ }, {
+ .chr_val_handle = 50,
+ .dsc_handle = 54,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x4444),
+ }, {
+ .chr_val_handle = 50,
+ .dsc_handle = 55,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x5555),
+ }, {
+ 0
+ } })
+ );
+
+ /*** Interleaved 16-bit and 128-bit descriptors. */
+ ble_gatt_disc_d_test_misc_all(50, 100, 0,
+ ((struct ble_gatt_disc_d_test_dsc[]) { {
+ .chr_val_handle = 50,
+ .dsc_handle = 51,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x1111),
+ }, {
+ .chr_val_handle = 50,
+ .dsc_handle = 52,
+ .dsc_uuid128 = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 },
+ }, {
+ .chr_val_handle = 50,
+ .dsc_handle = 53,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x3333),
+ }, {
+ .chr_val_handle = 50,
+ .dsc_handle = 54,
+ .dsc_uuid128 = { 1,0,4,0,6,9,17,7,8,43,7,4,12,43,19,35 },
+ }, {
+ .chr_val_handle = 50,
+ .dsc_handle = 55,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x5555),
+ }, {
+ 0
+ } })
+ );
+
+ /*** Ends with final handle ID. */
+ ble_gatt_disc_d_test_misc_all(50, 52, 0,
+ ((struct ble_gatt_disc_d_test_dsc[]) { {
+ .chr_val_handle = 50,
+ .dsc_handle = 51,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x1111),
+ }, {
+ .chr_val_handle = 50,
+ .dsc_handle = 52,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x2222),
+ }, {
+ 0
+ } })
+ );
+
+ /*** Stop after two descriptors. */
+ ble_gatt_disc_d_test_misc_all(50, 100, 2,
+ ((struct ble_gatt_disc_d_test_dsc[]) { {
+ .chr_val_handle = 50,
+ .dsc_handle = 51,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x1111),
+ }, {
+ .chr_val_handle = 50,
+ .dsc_handle = 52,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x2222),
+ }, {
+ .chr_val_handle = 50,
+ .dsc_handle = 53,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x3333),
+ }, {
+ .chr_val_handle = 50,
+ .dsc_handle = 54,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x4444),
+ }, {
+ .chr_val_handle = 50,
+ .dsc_handle = 55,
+ .dsc_uuid128 = BLE_UUID16_ARR(0x5555),
+ }, {
+ 0
+ } })
+ );
+}
+
+TEST_SUITE(ble_gatt_disc_d_test_suite)
+{
+ tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
+
+ ble_gatt_disc_d_test_1();
+}
+
+int
+ble_gatt_disc_d_test_all(void)
+{
+ ble_gatt_disc_d_test_suite();
+
+ return tu_any_failed;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/net/nimble/host/test/src/ble_gatt_disc_s_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_gatt_disc_s_test.c b/net/nimble/host/test/src/ble_gatt_disc_s_test.c
new file mode 100644
index 0000000..2e278d6
--- /dev/null
+++ b/net/nimble/host/test/src/ble_gatt_disc_s_test.c
@@ -0,0 +1,406 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 <string.h>
+#include <errno.h>
+#include "testutil/testutil.h"
+#include "nimble/ble.h"
+#include "host/ble_hs_test.h"
+#include "host/ble_uuid.h"
+#include "ble_hs_test_util.h"
+
+struct ble_gatt_disc_s_test_svc {
+ uint16_t start_handle;
+ uint16_t end_handle;
+ uint16_t uuid16;
+ uint8_t uuid128[16];
+};
+
+#define BLE_GATT_DISC_S_TEST_MAX_SERVICES 256
+static struct ble_gatt_svc
+ ble_gatt_disc_s_test_svcs[BLE_GATT_DISC_S_TEST_MAX_SERVICES];
+static int ble_gatt_disc_s_test_num_svcs;
+static int ble_gatt_disc_s_test_rx_complete;
+
+static void
+ble_gatt_disc_s_test_init(void)
+{
+ ble_hs_test_util_init();
+ ble_gatt_disc_s_test_num_svcs = 0;
+ ble_gatt_disc_s_test_rx_complete = 0;
+}
+
+static int
+ble_gatt_disc_s_test_misc_svc_length(struct ble_gatt_disc_s_test_svc *service)
+{
+ if (service->uuid16 != 0) {
+ return 6;
+ } else {
+ return 20;
+ }
+}
+
+static int
+ble_gatt_disc_s_test_misc_rx_all_rsp_once(
+ uint16_t conn_handle, struct ble_gatt_disc_s_test_svc *services)
+{
+ struct ble_att_read_group_type_rsp rsp;
+ uint8_t buf[1024];
+ int off;
+ int rc;
+ int i;
+
+ /* Send the pending ATT Read By Group Type Request. */
+ ble_hs_test_util_tx_all();
+
+ rsp.bagp_length = ble_gatt_disc_s_test_misc_svc_length(services);
+ ble_att_read_group_type_rsp_write(buf, BLE_ATT_READ_GROUP_TYPE_RSP_BASE_SZ,
+ &rsp);
+
+ off = BLE_ATT_READ_GROUP_TYPE_RSP_BASE_SZ;
+ for (i = 0; ; i++) {
+ if (services[i].start_handle == 0) {
+ /* No more services. */
+ break;
+ }
+
+ rc = ble_gatt_disc_s_test_misc_svc_length(services + i);
+ if (rc != rsp.bagp_length) {
+ /* UUID length is changing; Need a separate response. */
+ break;
+ }
+
+ htole16(buf + off, services[i].start_handle);
+ off += 2;
+
+ htole16(buf + off, services[i].end_handle);
+ off += 2;
+
+ if (services[i].uuid16 != 0) {
+ htole16(buf + off, services[i].uuid16);
+ off += 2;
+ } else {
+ memcpy(buf + off, services[i].uuid128, 16);
+ off += 16;
+ }
+ }
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+ buf, off);
+ TEST_ASSERT(rc == 0);
+
+ return i;
+}
+
+static void
+ble_gatt_disc_s_test_misc_rx_all_rsp(
+ uint16_t conn_handle, struct ble_gatt_disc_s_test_svc *services)
+{
+ int count;
+ int idx;
+
+ idx = 0;
+ while (services[idx].start_handle != 0) {
+ count = ble_gatt_disc_s_test_misc_rx_all_rsp_once(conn_handle,
+ services + idx);
+ idx += count;
+ }
+
+ if (services[idx - 1].end_handle != 0xffff) {
+ /* Send the pending ATT Request. */
+ ble_hs_test_util_tx_all();
+ ble_hs_test_util_rx_att_err_rsp(conn_handle,
+ BLE_ATT_OP_READ_GROUP_TYPE_REQ,
+ BLE_ATT_ERR_ATTR_NOT_FOUND,
+ services[idx - 1].start_handle);
+ }
+}
+
+static int
+ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(
+ uint16_t conn_handle, struct ble_gatt_disc_s_test_svc *services)
+{
+ uint8_t buf[1024];
+ int off;
+ int rc;
+ int i;
+
+ /* Send the pending ATT Find By Type Value Request. */
+ ble_hs_test_util_tx_all();
+
+ buf[0] = BLE_ATT_OP_FIND_TYPE_VALUE_RSP;
+ off = BLE_ATT_FIND_TYPE_VALUE_RSP_BASE_SZ;
+ for (i = 0; ; i++) {
+ if (services[i].start_handle == 0) {
+ /* No more services. */
+ break;
+ }
+
+ htole16(buf + off, services[i].start_handle);
+ off += 2;
+
+ htole16(buf + off, services[i].end_handle);
+ off += 2;
+ }
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+ buf, off);
+ TEST_ASSERT(rc == 0);
+
+ return i;
+}
+
+static void
+ble_gatt_disc_s_test_misc_rx_uuid_rsp(
+ uint16_t conn_handle, struct ble_gatt_disc_s_test_svc *services)
+{
+ int count;
+ int idx;
+
+ idx = 0;
+ while (services[idx].start_handle != 0) {
+ count = ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(conn_handle,
+ services + idx);
+ idx += count;
+ }
+
+ if (services[idx - 1].end_handle != 0xffff) {
+ /* Send the pending ATT Request. */
+ ble_hs_test_util_tx_all();
+ ble_hs_test_util_rx_att_err_rsp(conn_handle,
+ BLE_ATT_OP_FIND_TYPE_VALUE_REQ,
+ BLE_ATT_ERR_ATTR_NOT_FOUND,
+ services[idx - 1].start_handle);
+ }
+}
+
+static void
+ble_gatt_disc_s_test_misc_verify_services(
+ struct ble_gatt_disc_s_test_svc *services)
+{
+ uint16_t uuid16;
+ uint8_t *uuid128;
+ int i;
+
+ for (i = 0; services[i].start_handle != 0; i++) {
+ TEST_ASSERT(services[i].start_handle ==
+ ble_gatt_disc_s_test_svcs[i].start_handle);
+ TEST_ASSERT(services[i].end_handle ==
+ ble_gatt_disc_s_test_svcs[i].end_handle);
+
+ uuid128 = ble_gatt_disc_s_test_svcs[i].uuid128;
+ uuid16 = ble_uuid_128_to_16(uuid128);
+ if (uuid16 != 0) {
+ TEST_ASSERT(services[i].uuid16 == uuid16);
+ } else {
+ TEST_ASSERT(memcmp(services[i].uuid128, uuid128, 16) == 0);
+ }
+ }
+
+ TEST_ASSERT(i == ble_gatt_disc_s_test_num_svcs);
+ TEST_ASSERT(ble_gatt_disc_s_test_rx_complete);
+}
+
+static int
+ble_gatt_disc_s_test_misc_disc_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ const struct ble_gatt_svc *service,
+ void *arg)
+{
+ TEST_ASSERT(error != NULL);
+ TEST_ASSERT(!ble_gatt_disc_s_test_rx_complete);
+
+ switch (error->status) {
+ case 0:
+ TEST_ASSERT(service != NULL);
+ TEST_ASSERT_FATAL(ble_gatt_disc_s_test_num_svcs <
+ BLE_GATT_DISC_S_TEST_MAX_SERVICES);
+ ble_gatt_disc_s_test_svcs[ble_gatt_disc_s_test_num_svcs++] = *service;
+ break;
+
+ case BLE_HS_EDONE:
+ TEST_ASSERT(service == NULL);
+ ble_gatt_disc_s_test_rx_complete = 1;
+ break;
+
+ default:
+ TEST_ASSERT(0);
+ }
+
+ return 0;
+}
+
+static void
+ble_gatt_disc_s_test_misc_good_all(struct ble_gatt_disc_s_test_svc *services)
+{
+ int rc;
+
+ ble_gatt_disc_s_test_init();
+
+ ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+ NULL, NULL);
+
+ rc = ble_gattc_disc_all_svcs(2, ble_gatt_disc_s_test_misc_disc_cb, NULL);
+ TEST_ASSERT(rc == 0);
+
+ ble_gatt_disc_s_test_misc_rx_all_rsp(2, services);
+ ble_gatt_disc_s_test_misc_verify_services(services);
+}
+
+static void
+ble_gatt_disc_s_test_misc_good_uuid(
+ struct ble_gatt_disc_s_test_svc *services)
+{
+ int rc;
+
+ ble_gatt_disc_s_test_init();
+
+ ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+ NULL, NULL);
+
+ if (services[0].uuid16 != 0) {
+ rc = ble_uuid_16_to_128(services[0].uuid16, services[0].uuid128);
+ TEST_ASSERT_FATAL(rc == 0);
+ }
+ rc = ble_gattc_disc_svc_by_uuid(2, services[0].uuid128,
+ ble_gatt_disc_s_test_misc_disc_cb, NULL);
+ TEST_ASSERT(rc == 0);
+
+ ble_gatt_disc_s_test_misc_rx_uuid_rsp(2, services);
+ ble_gatt_disc_s_test_misc_verify_services(services);
+}
+
+TEST_CASE(ble_gatt_disc_s_test_disc_all)
+{
+ /*** One 128-bit service. */
+ ble_gatt_disc_s_test_misc_good_all((struct ble_gatt_disc_s_test_svc[]) {
+ { 1, 5, 0, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, },
+ { 0 }
+ });
+
+ /*** Two 128-bit services. */
+ ble_gatt_disc_s_test_misc_good_all((struct ble_gatt_disc_s_test_svc[]) {
+ { 1, 5, 0, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, },
+ { 10, 50, 0, {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, },
+ { 0 }
+ });
+
+ /*** Five 128-bit services. */
+ ble_gatt_disc_s_test_misc_good_all((struct ble_gatt_disc_s_test_svc[]) {
+ { 1, 5, 0, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, },
+ { 10, 50, 0, {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, },
+ { 80, 120, 0, {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, },
+ { 123, 678, 0, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }, },
+ { 751, 999, 0, {5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }, },
+ { 0 }
+ });
+
+ /*** One 128-bit service, one 16-bit-service. */
+ ble_gatt_disc_s_test_misc_good_all((struct ble_gatt_disc_s_test_svc[]) {
+ { 1, 5, 0, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, },
+ { 6, 7, 0x1234 },
+ { 0 }
+ });
+
+ /*** End with handle 0xffff. */
+ ble_gatt_disc_s_test_misc_good_all((struct ble_gatt_disc_s_test_svc[]) {
+ { 1, 5, 0, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, },
+ { 7, 0xffff, 0, {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, },
+ { 0 }
+ });
+}
+
+TEST_CASE(ble_gatt_disc_s_test_disc_service_uuid)
+{
+ /*** 128-bit service; one entry. */
+ ble_gatt_disc_s_test_misc_good_uuid((struct ble_gatt_disc_s_test_svc[]) {
+ { 1, 5, 0, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, },
+ { 0 }
+ });
+
+ /*** 128-bit service; two entries. */
+ ble_gatt_disc_s_test_misc_good_uuid((struct ble_gatt_disc_s_test_svc[]) {
+ { 1, 5, 0, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, },
+ { 8, 43, 0, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, },
+ { 0 }
+ });
+
+ /*** 128-bit service; five entries. */
+ ble_gatt_disc_s_test_misc_good_uuid((struct ble_gatt_disc_s_test_svc[]) {
+ { 1, 5, 0, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, },
+ { 8, 43, 0, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, },
+ { 67, 100, 0, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, },
+ { 102, 103, 0, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, },
+ { 262, 900, 0, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, },
+ { 0 }
+ });
+
+ /*** 128-bit service; end with handle 0xffff. */
+ ble_gatt_disc_s_test_misc_good_uuid((struct ble_gatt_disc_s_test_svc[]) {
+ { 1, 5, 0, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, },
+ { 7, 0xffff, 0, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, },
+ { 0 }
+ });
+
+ /*** 16-bit service; one entry. */
+ ble_gatt_disc_s_test_misc_good_uuid((struct ble_gatt_disc_s_test_svc[]) {
+ { 1, 5, 0x1234 },
+ { 0 }
+ });
+
+ /*** 16-bit service; two entries. */
+ ble_gatt_disc_s_test_misc_good_uuid((struct ble_gatt_disc_s_test_svc[]) {
+ { 1, 5, 0x1234 },
+ { 85, 243, 0x1234 },
+ { 0 }
+ });
+
+ /*** 16-bit service; five entries. */
+ ble_gatt_disc_s_test_misc_good_uuid((struct ble_gatt_disc_s_test_svc[]) {
+ { 1, 5, 0x1234 },
+ { 85, 243, 0x1234 },
+ { 382, 383, 0x1234 },
+ { 562, 898, 0x1234 },
+ { 902, 984, 0x1234 },
+ { 0 }
+ });
+
+ /*** 16-bit service; end with handle 0xffff. */
+ ble_gatt_disc_s_test_misc_good_uuid((struct ble_gatt_disc_s_test_svc[]) {
+ { 1, 5, 0x1234 },
+ { 9, 0xffff, 0x1234 },
+ { 0 }
+ });
+}
+
+TEST_SUITE(ble_gatt_disc_s_test_suite)
+{
+ tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
+
+ ble_gatt_disc_s_test_disc_all();
+ ble_gatt_disc_s_test_disc_service_uuid();
+}
+
+int
+ble_gatt_disc_s_test_all(void)
+{
+ ble_gatt_disc_s_test_suite();
+
+ return tu_any_failed;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/net/nimble/host/test/src/ble_gatt_find_s_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_gatt_find_s_test.c b/net/nimble/host/test/src/ble_gatt_find_s_test.c
new file mode 100644
index 0000000..c3ab93d
--- /dev/null
+++ b/net/nimble/host/test/src/ble_gatt_find_s_test.c
@@ -0,0 +1,342 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 <string.h>
+#include <errno.h>
+#include "testutil/testutil.h"
+#include "nimble/ble.h"
+#include "host/ble_hs_test.h"
+#include "host/ble_uuid.h"
+#include "ble_hs_test_util.h"
+
+static struct ble_gatt_svc ble_gatt_find_s_test_svcs[256];
+static int ble_gatt_find_s_test_num_svcs;
+static int ble_gatt_find_s_test_proc_complete;
+
+struct ble_gatt_find_s_test_entry {
+ uint16_t inc_handle; /* 0 indicates no more entries. */
+ uint16_t start_handle;
+ uint16_t end_handle;
+ uint8_t uuid128[16];
+};
+
+static void
+ble_gatt_find_s_test_misc_init(void)
+{
+ ble_hs_test_util_init();
+ ble_gatt_find_s_test_num_svcs = 0;
+ ble_gatt_find_s_test_proc_complete = 0;
+}
+
+static int
+ble_gatt_find_s_test_misc_cb(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ const struct ble_gatt_svc *service,
+ void *arg)
+{
+ TEST_ASSERT(!ble_gatt_find_s_test_proc_complete);
+ TEST_ASSERT(error != NULL);
+
+ switch (error->status) {
+ case 0:
+ ble_gatt_find_s_test_svcs[ble_gatt_find_s_test_num_svcs++] = *service;
+ break;
+
+ case BLE_HS_EDONE:
+ ble_gatt_find_s_test_proc_complete = 1;
+ break;
+
+ default:
+ TEST_ASSERT(0);
+ break;
+ }
+
+ return 0;
+}
+static int
+ble_gatt_find_s_test_misc_rx_read_type(
+ uint16_t conn_handle, struct ble_gatt_find_s_test_entry *entries)
+{
+ struct ble_att_read_type_rsp rsp;
+ uint16_t uuid16;
+ uint8_t buf[1024];
+ int off;
+ int rc;
+ int i;
+
+ memset(&rsp, 0, sizeof rsp);
+
+ off = BLE_ATT_READ_TYPE_RSP_BASE_SZ;
+ for (i = 0; entries[i].inc_handle != 0; i++) {
+ if (rsp.batp_length == BLE_GATTS_INC_SVC_LEN_NO_UUID + 2) {
+ break;
+ }
+
+ uuid16 = ble_uuid_128_to_16(entries[i].uuid128);
+ if (uuid16 == 0) {
+ if (rsp.batp_length != 0) {
+ break;
+ }
+ rsp.batp_length = BLE_GATTS_INC_SVC_LEN_NO_UUID + 2;
+ } else {
+ rsp.batp_length = BLE_GATTS_INC_SVC_LEN_UUID + 2;
+ }
+
+ TEST_ASSERT_FATAL(off + rsp.batp_length <= sizeof buf);
+
+ htole16(buf + off, entries[i].inc_handle);
+ off += 2;
+
+ htole16(buf + off, entries[i].start_handle);
+ off += 2;
+
+ htole16(buf + off, entries[i].end_handle);
+ off += 2;
+
+ if (uuid16 != 0) {
+ htole16(buf + off, uuid16);
+ off += 2;
+ }
+ }
+
+ if (i == 0) {
+ ble_hs_test_util_rx_att_err_rsp(conn_handle, BLE_ATT_OP_READ_TYPE_REQ,
+ BLE_ATT_ERR_ATTR_NOT_FOUND, 0);
+ return 0;
+ }
+
+ ble_att_read_type_rsp_write(buf + 0, BLE_ATT_READ_TYPE_RSP_BASE_SZ, &rsp);
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+ buf, off);
+ TEST_ASSERT(rc == 0);
+
+ return i;
+}
+
+static void
+ble_gatt_find_s_test_misc_rx_read(uint16_t conn_handle, uint8_t *uuid128)
+{
+ uint8_t buf[17];
+ int rc;
+
+ buf[0] = BLE_ATT_OP_READ_RSP;
+ memcpy(buf + 1, uuid128, 16);
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+ buf, 17);
+ TEST_ASSERT(rc == 0);
+}
+
+static void
+ble_gatt_find_s_test_misc_verify_tx_read_type(uint16_t start_handle,
+ uint16_t end_handle)
+{
+ struct ble_att_read_type_req req;
+ struct os_mbuf *om;
+ uint16_t uuid16;
+
+ ble_hs_test_util_tx_all();
+
+ om = ble_hs_test_util_prev_tx_dequeue_pullup();
+ TEST_ASSERT_FATAL(om != NULL);
+
+ ble_att_read_type_req_parse(om->om_data, om->om_len, &req);
+
+ TEST_ASSERT(req.batq_start_handle == start_handle);
+ TEST_ASSERT(req.batq_end_handle == end_handle);
+ TEST_ASSERT(om->om_len == BLE_ATT_READ_TYPE_REQ_BASE_SZ + 2);
+ uuid16 = le16toh(om->om_data + BLE_ATT_READ_TYPE_REQ_BASE_SZ);
+ TEST_ASSERT(uuid16 == BLE_ATT_UUID_INCLUDE);
+}
+
+static void
+ble_gatt_find_s_test_misc_verify_tx_read(uint16_t handle)
+{
+ struct ble_att_read_req req;
+ struct os_mbuf *om;
+
+ ble_hs_test_util_tx_all();
+
+ om = ble_hs_test_util_prev_tx_dequeue_pullup();
+ TEST_ASSERT_FATAL(om != NULL);
+
+ ble_att_read_req_parse(om->om_data, om->om_len, &req);
+
+ TEST_ASSERT(req.barq_handle == handle);
+ TEST_ASSERT(om->om_len == BLE_ATT_READ_REQ_SZ);
+}
+
+static void
+ble_gatt_find_s_test_misc_find_inc(uint16_t conn_handle,
+ uint16_t start_handle, uint16_t end_handle,
+ struct ble_gatt_find_s_test_entry *entries)
+{
+ struct ble_gatt_svc service;
+ int cur_start;
+ int num_found;
+ int idx;
+ int rc;
+ int i;
+
+ rc = ble_gattc_find_inc_svcs(conn_handle, start_handle, end_handle,
+ ble_gatt_find_s_test_misc_cb, &service);
+ TEST_ASSERT(rc == 0);
+
+ cur_start = start_handle;
+ idx = 0;
+ while (1) {
+ ble_gatt_find_s_test_misc_verify_tx_read_type(cur_start, end_handle);
+ num_found = ble_gatt_find_s_test_misc_rx_read_type(conn_handle,
+ entries + idx);
+ if (num_found == 0) {
+ break;
+ }
+
+ if (ble_uuid_128_to_16(entries[idx].uuid128) == 0) {
+ TEST_ASSERT(num_found == 1);
+ ble_gatt_find_s_test_misc_verify_tx_read(
+ entries[idx].start_handle);
+ ble_gatt_find_s_test_misc_rx_read(conn_handle,
+ entries[idx].uuid128);
+ }
+
+ idx += num_found;
+ cur_start = entries[idx - 1].inc_handle + 1;
+ }
+ TEST_ASSERT(idx == ble_gatt_find_s_test_num_svcs);
+ TEST_ASSERT(ble_gatt_find_s_test_proc_complete);
+
+ for (i = 0; i < ble_gatt_find_s_test_num_svcs; i++) {
+ TEST_ASSERT(ble_gatt_find_s_test_svcs[i].start_handle ==
+ entries[i].start_handle);
+ TEST_ASSERT(ble_gatt_find_s_test_svcs[i].end_handle ==
+ entries[i].end_handle);
+ TEST_ASSERT(memcmp(ble_gatt_find_s_test_svcs[i].uuid128,
+ entries[i].uuid128, 16) == 0);
+ }
+}
+
+TEST_CASE(ble_gatt_find_s_test_1)
+{
+ /* Two 16-bit UUID services; one response. */
+ ble_gatt_find_s_test_misc_init();
+ ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+ NULL, NULL);
+ ble_gatt_find_s_test_misc_find_inc(2, 5, 10,
+ ((struct ble_gatt_find_s_test_entry[]) { {
+ .inc_handle = 6,
+ .start_handle = 35,
+ .end_handle = 49,
+ .uuid128 = BLE_UUID16_ARR(0x5155),
+ }, {
+ .inc_handle = 9,
+ .start_handle = 543,
+ .end_handle = 870,
+ .uuid128 = BLE_UUID16_ARR(0x1122),
+ }, {
+ 0,
+ } })
+ );
+
+ /* One 128-bit UUID service; two responses. */
+ ble_gatt_find_s_test_misc_init();
+ ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+ NULL, NULL);
+ ble_gatt_find_s_test_misc_find_inc(2, 34, 100,
+ ((struct ble_gatt_find_s_test_entry[]) { {
+ .inc_handle = 36,
+ .start_handle = 403,
+ .end_handle = 859,
+ .uuid128 = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 },
+ }, {
+ 0,
+ } })
+ );
+
+ /* Two 128-bit UUID service; four responses. */
+ ble_gatt_find_s_test_misc_init();
+ ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+ NULL, NULL);
+ ble_gatt_find_s_test_misc_find_inc(2, 34, 100,
+ ((struct ble_gatt_find_s_test_entry[]) { {
+ .inc_handle = 36,
+ .start_handle = 403,
+ .end_handle = 859,
+ .uuid128 = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 },
+ }, {
+ .inc_handle = 39,
+ .start_handle = 900,
+ .end_handle = 932,
+ .uuid128 = { 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 },
+ }, {
+ 0,
+ } })
+ );
+
+ /* Two 16-bit UUID; three 128-bit UUID; seven responses. */
+ ble_gatt_find_s_test_misc_init();
+ ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+ NULL, NULL);
+ ble_gatt_find_s_test_misc_find_inc(2, 1, 100,
+ ((struct ble_gatt_find_s_test_entry[]) { {
+ .inc_handle = 36,
+ .start_handle = 403,
+ .end_handle = 859,
+ .uuid128 = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 },
+ }, {
+ .inc_handle = 37,
+ .start_handle = 35,
+ .end_handle = 49,
+ .uuid128 = BLE_UUID16_ARR(0x5155),
+ }, {
+ .inc_handle = 38,
+ .start_handle = 543,
+ .end_handle = 870,
+ .uuid128 = BLE_UUID16_ARR(0x1122),
+ }, {
+ .inc_handle = 39,
+ .start_handle = 900,
+ .end_handle = 932,
+ .uuid128 = { 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 },
+ }, {
+ .inc_handle = 40,
+ .start_handle = 940,
+ .end_handle = 950,
+ .uuid128 = { 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 },
+ }, {
+ 0,
+ } })
+ );
+}
+
+TEST_SUITE(ble_gatt_find_s_test_suite)
+{
+ tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
+
+ ble_gatt_find_s_test_1();
+}
+
+int
+ble_gatt_find_s_test_all(void)
+{
+ ble_gatt_find_s_test_suite();
+
+ return tu_any_failed;
+}