blob: 0faa6713d59b0ba2160faf2bfc8aba018063cdef [file] [log] [blame]
/*
* Copyright (c) 2023 Demant A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/bluetooth/audio/cap.h>
#include <zephyr/bluetooth/audio/csip.h>
#include "common.h"
extern enum bst_result_t bst_result;
static struct bt_csip_set_member_svc_inst *svc_inst;
static bool is_peer_subscribed(struct bt_conn *conn)
{
struct bt_gatt_attr *attr;
attr = bt_gatt_find_by_uuid(NULL, 0, BT_UUID_CSIS_SET_LOCK);
if (!attr) {
printk("No BT_UUID_PACS_SNK attribute found\n");
return false;
}
return bt_gatt_is_subscribed(conn, attr, BT_GATT_CCC_NOTIFY);
}
static void csip_set_member_lock_changed_cb(struct bt_conn *conn,
struct bt_csip_set_member_svc_inst *svc_inst,
bool locked)
{
printk("Client %p %s the lock\n", conn, locked ? "locked" : "released");
}
static struct bt_csip_set_member_cb csip_cb = {
.lock_changed = csip_set_member_lock_changed_cb,
};
static void test_main(void)
{
int err;
const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
};
struct bt_csip_set_member_register_param csip_params = {
.set_size = 1,
.rank = 1,
.lockable = true,
.cb = &csip_cb,
};
printk("Enabling Bluetooth\n");
err = bt_enable(NULL);
if (err != 0) {
FAIL("Bluetooth enable failed (err %d)\n", err);
return;
}
printk("Registering CSIP Set Member\n");
err = bt_cap_acceptor_register(&csip_params, &svc_inst);
if (err != 0) {
printk("Failed to register csip\n");
return;
}
printk("Start Advertising\n");
err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0);
if (err != 0) {
FAIL("Advertising failed to start (err %d)\n", err);
return;
}
printk("Waiting to be connected\n");
WAIT_FOR_FLAG(flag_connected);
printk("Connected\n");
printk("Waiting to be subscribed\n");
while (!is_peer_subscribed(default_conn)) {
(void)k_sleep(K_MSEC(10));
}
printk("Subscribed\n");
err = bt_csip_set_member_lock(svc_inst, true, false);
if (err != 0) {
FAIL("Failed to set lock (err %d)\n", err);
return;
}
/* Now wait for client to disconnect, then stop adv so it does not reconnect */
printk("Wait for client disconnect\n");
WAIT_FOR_UNSET_FLAG(flag_connected);
printk("Client disconnected\n");
err = bt_le_adv_stop();
if (err != 0) {
FAIL("Advertising failed to stop (err %d)\n", err);
return;
}
/* Trigger changes while device is disconnected */
err = bt_csip_set_member_lock(svc_inst, false, false);
if (err != 0) {
FAIL("Failed to set lock (err %d)\n", err);
return;
}
printk("Start Advertising\n");
err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0);
if (err != 0) {
FAIL("Advertising failed to start (err %d)\n", err);
return;
}
WAIT_FOR_FLAG(flag_connected);
WAIT_FOR_UNSET_FLAG(flag_connected);
PASS("CSIP Notify Server passed\n");
}
static const struct bst_test_instance test_csip_notify_server[] = {
{
.test_id = "csip_notify_server",
.test_post_init_f = test_init,
.test_tick_f = test_tick,
.test_main_f = test_main,
},
BSTEST_END_MARKER,
};
struct bst_test_list *test_csip_notify_server_install(struct bst_test_list *tests)
{
return bst_add_tests(tests, test_csip_notify_server);
}