/*
|
* 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 "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_arg {
|
uint16_t exp_conn_handle;
|
int exp_status;
|
int called;
|
};
|
|
static struct ble_gap_event ble_gatt_conn_test_gap_event;
|
|
static void
|
ble_gatt_conn_test_util_init(void)
|
{
|
ble_hs_test_util_init();
|
memset(&ble_gatt_conn_test_gap_event, -1,
|
sizeof ble_gatt_conn_test_gap_event);
|
}
|
|
static int
|
ble_gatt_conn_test_indicate_cb(struct ble_gap_event *event, void *arg)
|
{
|
/* Only record indication failures. */
|
if (event->type == BLE_GAP_EVENT_NOTIFY_TX &&
|
event->notify_tx.status != 0) {
|
|
ble_gatt_conn_test_gap_event = *event;
|
}
|
return 0;
|
}
|
|
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_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 == cb_arg->exp_status);
|
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_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 == cb_arg->exp_status);
|
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_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 == cb_arg->exp_status);
|
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_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 == cb_arg->exp_status);
|
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_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 == cb_arg->exp_status);
|
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_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 == cb_arg->exp_status);
|
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_val_handle,
|
const struct ble_gatt_dsc *dsc,
|
void *arg)
|
{
|
struct ble_gatt_conn_test_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 == cb_arg->exp_status);
|
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_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 == cb_arg->exp_status);
|
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_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 == cb_arg->exp_status);
|
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_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 == cb_arg->exp_status);
|
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_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 == cb_arg->exp_status);
|
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_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 == cb_arg->exp_status);
|
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_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 == cb_arg->exp_status);
|
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_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 == cb_arg->exp_status);
|
TEST_ASSERT(attrs != NULL);
|
|
cb_arg->called++;
|
|
return 0;
|
}
|
|
TEST_CASE_SELF(ble_gatt_conn_test_disconnect)
|
{
|
struct ble_gatt_conn_test_arg mtu_arg = { 0, BLE_HS_ENOTCONN };
|
struct ble_gatt_conn_test_arg disc_all_svcs_arg = { 0, BLE_HS_ENOTCONN };
|
struct ble_gatt_conn_test_arg disc_svc_uuid_arg = { 0, BLE_HS_ENOTCONN };
|
struct ble_gatt_conn_test_arg find_inc_svcs_arg = { 0, BLE_HS_ENOTCONN };
|
struct ble_gatt_conn_test_arg disc_all_chrs_arg = { 0, BLE_HS_ENOTCONN };
|
struct ble_gatt_conn_test_arg disc_chr_uuid_arg = { 0, BLE_HS_ENOTCONN };
|
struct ble_gatt_conn_test_arg disc_all_dscs_arg = { 0, BLE_HS_ENOTCONN };
|
struct ble_gatt_conn_test_arg read_arg = { 0, BLE_HS_ENOTCONN };
|
struct ble_gatt_conn_test_arg read_uuid_arg = { 0, BLE_HS_ENOTCONN };
|
struct ble_gatt_conn_test_arg read_long_arg = { 0, BLE_HS_ENOTCONN };
|
struct ble_gatt_conn_test_arg read_mult_arg = { 0, BLE_HS_ENOTCONN };
|
struct ble_gatt_conn_test_arg write_arg = { 0, BLE_HS_ENOTCONN };
|
struct ble_gatt_conn_test_arg write_long_arg = { 0, BLE_HS_ENOTCONN };
|
struct ble_gatt_conn_test_arg write_rel_arg = { 0, BLE_HS_ENOTCONN };
|
struct ble_gatt_attr attr;
|
uint16_t attr_handle;
|
uint16_t offset = 0;
|
int rc;
|
|
ble_gatt_conn_test_util_init();
|
|
/*** Register an attribute to allow indicatations to be sent. */
|
rc = ble_att_svr_register(BLE_UUID16_DECLARE(0x1212), BLE_ATT_F_READ, 0,
|
&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}),
|
ble_gatt_conn_test_indicate_cb, NULL);
|
ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
|
ble_gatt_conn_test_indicate_cb, NULL);
|
ble_hs_test_util_create_conn(3, ((uint8_t[]){3,4,5,6,7,8,9,10}),
|
ble_gatt_conn_test_indicate_cb, 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_DECLARE(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_DECLARE(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_DECLARE(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, offset,
|
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);
|
|
rc = ble_gatts_indicate(3, attr_handle);
|
TEST_ASSERT_FATAL(rc == 0);
|
|
/*** Start the procedures. */
|
|
/*** 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);
|
TEST_ASSERT(ble_gatt_conn_test_gap_event.type == 255);
|
|
/* 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);
|
TEST_ASSERT(ble_gatt_conn_test_gap_event.type == 255);
|
|
/* 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_ASSERT(ble_gatt_conn_test_gap_event.type == BLE_GAP_EVENT_NOTIFY_TX);
|
TEST_ASSERT(ble_gatt_conn_test_gap_event.notify_tx.status ==
|
BLE_HS_ENOTCONN);
|
TEST_ASSERT(ble_gatt_conn_test_gap_event.notify_tx.conn_handle == 3);
|
TEST_ASSERT(ble_gatt_conn_test_gap_event.notify_tx.attr_handle ==
|
attr_handle);
|
TEST_ASSERT(ble_gatt_conn_test_gap_event.notify_tx.indication);
|
|
ble_hs_test_util_assert_mbufs_freed(NULL);
|
}
|
|
static void
|
ble_gatt_conn_test_util_timeout(uint16_t conn_handle,
|
struct ble_gatt_conn_test_arg *arg)
|
{
|
int32_t ticks_from_now;
|
|
ticks_from_now = ble_gattc_timer();
|
TEST_ASSERT(ticks_from_now == 30 * OS_TICKS_PER_SEC);
|
|
os_time_advance(29 * OS_TICKS_PER_SEC);
|
ticks_from_now = ble_gattc_timer();
|
TEST_ASSERT(ticks_from_now == 1 * OS_TICKS_PER_SEC);
|
|
ble_hs_test_util_hci_ack_set_disconnect(0);
|
os_time_advance(1 * OS_TICKS_PER_SEC);
|
ticks_from_now = ble_gattc_timer();
|
TEST_ASSERT(ticks_from_now == BLE_HS_FOREVER);
|
|
/* Ensure connection was terminated due to proecedure timeout. */
|
ble_hs_test_util_hci_rx_disconn_complete_event(conn_handle, 0,
|
BLE_ERR_REM_USER_CONN_TERM);
|
|
/* Ensure GATT callback was called with timeout status. */
|
if (arg != NULL) {
|
TEST_ASSERT(arg->called == 1);
|
}
|
}
|
|
TEST_CASE_SELF(ble_gatt_conn_test_timeout)
|
{
|
static const uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
|
|
struct ble_gatt_conn_test_arg mtu_arg = { 1, BLE_HS_ETIMEOUT };
|
struct ble_gatt_conn_test_arg disc_all_svcs_arg = { 1, BLE_HS_ETIMEOUT };
|
struct ble_gatt_conn_test_arg disc_svc_uuid_arg = { 1, BLE_HS_ETIMEOUT };
|
struct ble_gatt_conn_test_arg find_inc_svcs_arg = { 1, BLE_HS_ETIMEOUT };
|
struct ble_gatt_conn_test_arg disc_all_chrs_arg = { 1, BLE_HS_ETIMEOUT };
|
struct ble_gatt_conn_test_arg disc_chr_uuid_arg = { 1, BLE_HS_ETIMEOUT };
|
struct ble_gatt_conn_test_arg disc_all_dscs_arg = { 1, BLE_HS_ETIMEOUT };
|
struct ble_gatt_conn_test_arg read_arg = { 1, BLE_HS_ETIMEOUT };
|
struct ble_gatt_conn_test_arg read_uuid_arg = { 1, BLE_HS_ETIMEOUT };
|
struct ble_gatt_conn_test_arg read_long_arg = { 1, BLE_HS_ETIMEOUT };
|
struct ble_gatt_conn_test_arg read_mult_arg = { 1, BLE_HS_ETIMEOUT };
|
struct ble_gatt_conn_test_arg write_arg = { 1, BLE_HS_ETIMEOUT };
|
struct ble_gatt_conn_test_arg write_long_arg = { 1, BLE_HS_ETIMEOUT };
|
struct ble_gatt_conn_test_arg write_rel_arg = { 1, BLE_HS_ETIMEOUT };
|
|
struct ble_gatt_attr attr;
|
int32_t ticks_from_now;
|
uint16_t attr_handle;
|
uint16_t offset = 0;
|
int rc;
|
|
ble_gatt_conn_test_util_init();
|
|
ticks_from_now = ble_gattc_timer();
|
TEST_ASSERT(ticks_from_now == BLE_HS_FOREVER);
|
|
/*** Register an attribute to allow indicatations to be sent. */
|
rc = ble_att_svr_register(BLE_UUID16_DECLARE(0x1212), BLE_ATT_F_READ, 0,
|
&attr_handle,
|
ble_gatt_conn_test_attr_cb, NULL);
|
TEST_ASSERT(rc == 0);
|
|
/*** MTU. */
|
ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
|
rc = ble_gattc_exchange_mtu(1, ble_gatt_conn_test_mtu_cb, &mtu_arg);
|
TEST_ASSERT_FATAL(rc == 0);
|
ble_gatt_conn_test_util_timeout(1, &mtu_arg);
|
|
/*** Discover all services. */
|
ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
|
rc = ble_gattc_disc_all_svcs(1, ble_gatt_conn_test_disc_all_svcs_cb,
|
&disc_all_svcs_arg);
|
TEST_ASSERT_FATAL(rc == 0);
|
ble_gatt_conn_test_util_timeout(1, &disc_all_svcs_arg);
|
|
/*** Discover services by UUID. */
|
ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
|
rc = ble_gattc_disc_svc_by_uuid(1, BLE_UUID16_DECLARE(0x1111),
|
ble_gatt_conn_test_disc_svc_uuid_cb,
|
&disc_svc_uuid_arg);
|
TEST_ASSERT_FATAL(rc == 0);
|
ble_gatt_conn_test_util_timeout(1, &disc_svc_uuid_arg);
|
|
/*** Find included services. */
|
ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
|
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);
|
ble_gatt_conn_test_util_timeout(1, &find_inc_svcs_arg);
|
|
/*** Discover all characteristics. */
|
ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
|
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);
|
ble_gatt_conn_test_util_timeout(1, &disc_all_chrs_arg);
|
|
/*** Discover all descriptors. */
|
ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
|
rc = ble_gattc_disc_all_dscs(1, 3, 0xffff,
|
ble_gatt_conn_test_disc_all_dscs_cb,
|
&disc_chr_uuid_arg);
|
TEST_ASSERT_FATAL(rc == 0);
|
ble_gatt_conn_test_util_timeout(1, &disc_chr_uuid_arg);
|
|
/*** Discover characteristics by UUID. */
|
ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
|
rc = ble_gattc_disc_chrs_by_uuid(1, 2, 0xffff, BLE_UUID16_DECLARE(0x2222),
|
ble_gatt_conn_test_disc_chr_uuid_cb,
|
&disc_all_dscs_arg);
|
TEST_ASSERT_FATAL(rc == 0);
|
ble_gatt_conn_test_util_timeout(1, &disc_all_dscs_arg);
|
|
/*** Read. */
|
ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
|
rc = ble_gattc_read(1, BLE_GATT_BREAK_TEST_READ_ATTR_HANDLE,
|
ble_gatt_conn_test_read_cb, &read_arg);
|
TEST_ASSERT_FATAL(rc == 0);
|
ble_gatt_conn_test_util_timeout(1, &read_arg);
|
|
/*** Read by UUID. */
|
ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
|
rc = ble_gattc_read_by_uuid(1, 1, 0xffff, BLE_UUID16_DECLARE(0x3333),
|
ble_gatt_conn_test_read_uuid_cb,
|
&read_uuid_arg);
|
TEST_ASSERT_FATAL(rc == 0);
|
ble_gatt_conn_test_util_timeout(1, &read_uuid_arg);
|
|
/*** Read long. */
|
ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
|
rc = ble_gattc_read_long(1, BLE_GATT_BREAK_TEST_READ_ATTR_HANDLE, offset,
|
ble_gatt_conn_test_read_long_cb,
|
&read_long_arg);
|
TEST_ASSERT_FATAL(rc == 0);
|
ble_gatt_conn_test_util_timeout(1, &read_long_arg);
|
|
/*** Read multiple. */
|
ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
|
rc = ble_gattc_read_mult(1, ((uint16_t[3]){5,6,7}), 3,
|
ble_gatt_conn_test_read_mult_cb,
|
&read_mult_arg);
|
TEST_ASSERT_FATAL(rc == 0);
|
ble_gatt_conn_test_util_timeout(1, &read_mult_arg);
|
|
/*** Write. */
|
ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
|
rc = ble_hs_test_util_gatt_write_flat(
|
1, 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);
|
ble_gatt_conn_test_util_timeout(1, &write_arg);
|
|
/*** Write long. */
|
ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
|
rc = ble_hs_test_util_gatt_write_long_flat(
|
1, 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);
|
ble_gatt_conn_test_util_timeout(1, &write_long_arg);
|
|
/*** Write reliable. */
|
ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
|
attr.handle = 8;
|
attr.offset = 0;
|
attr.om = os_msys_get_pkthdr(0, 0);
|
rc = ble_gattc_write_reliable(
|
1, &attr, 1, ble_gatt_conn_test_write_rel_cb, &write_rel_arg);
|
TEST_ASSERT_FATAL(rc == 0);
|
ble_gatt_conn_test_util_timeout(1, &write_rel_arg);
|
|
/*** Indication. */
|
ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
|
rc = ble_gatts_indicate(1, attr_handle);
|
TEST_ASSERT_FATAL(rc == 0);
|
ble_gatt_conn_test_util_timeout(1, NULL);
|
|
ble_hs_test_util_assert_mbufs_freed(NULL);
|
}
|
|
TEST_SUITE(ble_gatt_conn_suite)
|
{
|
ble_gatt_conn_test_disconnect();
|
ble_gatt_conn_test_timeout();
|
}
|