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; +}