/* * Copyright (c) 2023 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #include "utils.h" #include "gatt_utils.h" #include #include #include #include #include #include #include void client_round_0(void) { struct bt_conn *conn; printk("start round 0...........\n"); conn = connect_as_peripheral(); printk("connected: conn %p\n", conn); gatt_discover(); activate_robust_caching(); /* subscribe to the SC indication, so we don't have to ATT read to * become change-aware. */ gatt_subscribe_to_service_changed(true); read_test_char(true); /* We should normally wait until we are bonded to write the CCC / CF * characteristics, but here we bond after the fact on purpose, to * simulate a client that has this exact behavior. * The CCC and CF should still persist on reboot. */ wait_bonded(); disconnect(conn); } void client_round_1(void) { struct bt_conn *conn; printk("start round 1...........\n"); conn = connect_as_peripheral(); printk("connected: conn %p\n", conn); wait_secured(); /* server should remember we are change-aware */ read_test_char(true); disconnect(conn); } void client_round_2(void) { struct bt_conn *conn; printk("start round 2...........\n"); conn = connect_as_peripheral(); printk("connected: conn %p\n", conn); wait_secured(); /* We are change-unaware. wait until the Service Changed indication is * received, that should then make us change-aware. */ wait_for_sc_indication(); read_test_char(true); /* We sleep just enough so that the server's `delayed store` work item * is executed. We still trigger a disconnect, even though the server * device will be unresponsive for this round. */ k_sleep(K_MSEC(CONFIG_BT_SETTINGS_DELAYED_STORE_MS)); disconnect(conn); } void client_round_3(void) { struct bt_conn *conn; printk("start round 3...........\n"); conn = connect_as_peripheral(); printk("connected: conn %p\n", conn); wait_secured(); /* server should remember we are change-aware */ read_test_char(true); /* Unsubscribe from the SC indication. * * In the next round, we will be change-unaware, so the first ATT read * will fail, but the second one will succeed and we will be marked as * change-aware again. */ gatt_subscribe_to_service_changed(false); disconnect(conn); } void client_round_4(void) { struct bt_conn *conn; printk("start round 4...........\n"); conn = connect_as_peripheral(); printk("connected: conn %p\n", conn); wait_secured(); /* GATT DB has changed again. * Before disc: svc1 * After disc: svc1 + svc2 * At boot: svc1 * Expect a failure on the first read of the same GATT handle. */ read_test_char(false); read_test_char(true); disconnect(conn); } void client_round_5(void) { printk("start round 5...........\n"); printk("don't need to do anything, central will " "not connect to us\n"); } void client_round_6(void) { struct bt_conn *conn; printk("start round 6...........\n"); conn = connect_as_peripheral(); printk("connected: conn %p\n", conn); wait_secured(); /* GATT DB has changed again. * Expect a failure on the first read of the same GATT handle. */ read_test_char(false); read_test_char(true); disconnect(conn); } void client_procedure(void) { bt_enable(NULL); settings_load(); client_round_0(); client_round_1(); client_round_2(); client_round_3(); client_round_4(); client_round_5(); client_round_6(); PASS("PASS\n"); }