tests: Bluetooth: ascs: Add test for ASE release on ACL disconnection
This adds test case to verify if ACL disconnects, the associated ASE is released. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
This commit is contained in:
parent
f5d4e9e0db
commit
6c6a66711c
|
@ -14,6 +14,7 @@
|
|||
#include <zephyr/bluetooth/audio/bap.h>
|
||||
#include <zephyr/bluetooth/audio/pacs.h>
|
||||
#include <zephyr/bluetooth/conn.h>
|
||||
#include <zephyr/bluetooth/hci_err.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
#include <zephyr/sys/util_macro.h>
|
||||
|
@ -220,3 +221,79 @@ ZTEST_F(ascs_test_suite, test_abort_client_operation_if_callback_not_registered)
|
|||
param->response_code);
|
||||
zassert_equal(0x00, param->reason, "unexpected Reason 0x%02x", param->reason);
|
||||
}
|
||||
|
||||
ZTEST_F(ascs_test_suite, test_release_ase_on_acl_disconnection_client_terminates_cis)
|
||||
{
|
||||
struct bt_bap_stream *stream = &fixture->stream;
|
||||
struct bt_conn *conn = &fixture->conn;
|
||||
const struct bt_gatt_attr *ase;
|
||||
struct bt_iso_chan *chan;
|
||||
uint8_t ase_id;
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK)) {
|
||||
ase = fixture->ase_snk.attr;
|
||||
ase_id = fixture->ase_snk.id;
|
||||
} else {
|
||||
ase = fixture->ase_src.attr;
|
||||
ase_id = fixture->ase_src.id;
|
||||
}
|
||||
|
||||
zexpect_not_null(ase);
|
||||
zexpect_true(ase_id != 0x00);
|
||||
|
||||
bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb);
|
||||
|
||||
/* Set ASE to non-idle state */
|
||||
test_preamble_state_streaming(conn, ase_id, stream, &chan,
|
||||
!IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK));
|
||||
|
||||
/* Mock ACL disconnection */
|
||||
mock_bt_conn_disconnected(conn, BT_HCI_ERR_CONN_TIMEOUT);
|
||||
|
||||
/* Mock CIS disconnection */
|
||||
mock_bt_iso_disconnect(chan);
|
||||
|
||||
/* Expected to notify the upper layers */
|
||||
expect_bt_bap_unicast_server_cb_release_called_once(stream);
|
||||
expect_bt_bap_stream_ops_released_called_once(stream);
|
||||
|
||||
bt_bap_unicast_server_unregister_cb(&mock_bap_unicast_server_cb);
|
||||
}
|
||||
|
||||
ZTEST_F(ascs_test_suite, test_release_ase_on_acl_disconnection_server_terminates_cis)
|
||||
{
|
||||
struct bt_bap_stream *stream = &fixture->stream;
|
||||
struct bt_conn *conn = &fixture->conn;
|
||||
const struct bt_gatt_attr *ase;
|
||||
struct bt_iso_chan *chan;
|
||||
uint8_t ase_id;
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK)) {
|
||||
ase = fixture->ase_snk.attr;
|
||||
ase_id = fixture->ase_snk.id;
|
||||
} else {
|
||||
ase = fixture->ase_src.attr;
|
||||
ase_id = fixture->ase_src.id;
|
||||
}
|
||||
|
||||
zexpect_not_null(ase);
|
||||
zexpect_true(ase_id != 0x00);
|
||||
|
||||
bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb);
|
||||
|
||||
/* Set ASE to non-idle state */
|
||||
test_preamble_state_streaming(conn, ase_id, stream, &chan,
|
||||
!IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK));
|
||||
|
||||
/* Mock ACL disconnection */
|
||||
mock_bt_conn_disconnected(conn, BT_HCI_ERR_CONN_TIMEOUT);
|
||||
|
||||
/* Client does not disconnect the CIS in expected time */
|
||||
k_sleep(K_MSEC(CONFIG_BT_ASCS_ISO_DISCONNECT_DELAY));
|
||||
|
||||
/* Expected to notify the upper layers */
|
||||
expect_bt_bap_unicast_server_cb_release_called_once(stream);
|
||||
expect_bt_bap_stream_ops_released_called_once(stream);
|
||||
|
||||
bt_bap_unicast_server_unregister_cb(&mock_bap_unicast_server_cb);
|
||||
}
|
||||
|
|
|
@ -14,4 +14,6 @@ struct bt_conn {
|
|||
struct bt_conn_info info;
|
||||
};
|
||||
|
||||
void mock_bt_conn_disconnected(struct bt_conn *conn, uint8_t err);
|
||||
|
||||
#endif /* MOCKS_CONN_H_ */
|
||||
|
|
|
@ -29,3 +29,12 @@ void bt_conn_unref(struct bt_conn *conn)
|
|||
{
|
||||
|
||||
}
|
||||
|
||||
void mock_bt_conn_disconnected(struct bt_conn *conn, uint8_t err)
|
||||
{
|
||||
STRUCT_SECTION_FOREACH(bt_conn_cb, cb) {
|
||||
if (cb->disconnected) {
|
||||
cb->disconnected(conn, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,10 +38,12 @@ int k_work_reschedule(struct k_work_delayable *dwork, k_timeout_t delay)
|
|||
/* Determine whether the work item is queued already. */
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(&work_pending, work, node) {
|
||||
if (work == &dwork->work) {
|
||||
dwork->timeout.dticks = delay.ticks;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
dwork->timeout.dticks = delay.ticks;
|
||||
sys_slist_append(&work_pending, &dwork->work.node);
|
||||
|
||||
return 0;
|
||||
|
@ -54,6 +56,27 @@ int k_work_cancel_delayable(struct k_work_delayable *dwork)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t k_sleep(k_timeout_t timeout)
|
||||
{
|
||||
struct k_work *work;
|
||||
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(&work_pending, work, node) {
|
||||
if (work->flags & K_WORK_DELAYED) {
|
||||
struct k_work_delayable *dwork = k_work_delayable_from_work(work);
|
||||
|
||||
if (dwork->timeout.dticks > timeout.ticks) {
|
||||
dwork->timeout.dticks -= timeout.ticks;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
(void)sys_slist_remove(&work_pending, NULL, &work->node);
|
||||
work->handler(work);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mock_kernel_init(void)
|
||||
{
|
||||
FFF_FAKES_LIST(RESET_FAKE);
|
||||
|
|
Loading…
Reference in a new issue