1 /*
2  * Copyright (c) 2023 Demant A/S
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdbool.h>
8 #include <stddef.h>
9 
10 #include <zephyr/bluetooth/audio/csip.h>
11 #include <zephyr/bluetooth/bluetooth.h>
12 #include <zephyr/bluetooth/conn.h>
13 #include <zephyr/bluetooth/gatt.h>
14 #include <zephyr/bluetooth/hci_types.h>
15 #include <zephyr/sys/printk.h>
16 
17 #include "bstests.h"
18 #include "common.h"
19 #include "common/bt_str.h"
20 
21 extern enum bst_result_t bst_result;
22 
23 CREATE_FLAG(flag_csip_set_lock_discovered);
24 CREATE_FLAG(flag_all_notifications_received);
25 
csip_discover_cb(struct bt_conn * conn,const struct bt_csip_set_coordinator_set_member * member,int err,size_t set_count)26 static void csip_discover_cb(struct bt_conn *conn,
27 			     const struct bt_csip_set_coordinator_set_member *member,
28 			     int err, size_t set_count)
29 {
30 	if (err != 0) {
31 		FAIL("CSIP Lock Discover failed (err = %d)\n", err);
32 		return;
33 	}
34 
35 	if (member->insts->info.lockable) {
36 		SET_FLAG(flag_csip_set_lock_discovered);
37 	}
38 }
39 
csip_lock_changed(struct bt_csip_set_coordinator_csis_inst * inst,bool locked)40 static void csip_lock_changed(struct bt_csip_set_coordinator_csis_inst *inst, bool locked)
41 {
42 	SET_FLAG(flag_all_notifications_received);
43 }
44 
45 static struct bt_csip_set_coordinator_cb cbs = {
46 	.lock_changed = csip_lock_changed,
47 	.discover = csip_discover_cb,
48 };
49 
test_main(void)50 static void test_main(void)
51 {
52 	int err;
53 
54 	printk("Enabling Bluetooth\n");
55 	err = bt_enable(NULL);
56 	if (err != 0) {
57 		FAIL("Bluetooth enable failed (err %d)\n", err);
58 		return;
59 	}
60 
61 	bt_le_scan_cb_register(&common_scan_cb);
62 	bt_csip_set_coordinator_register_cb(&cbs);
63 
64 	printk("Starting scan\n");
65 	err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL);
66 	if (err != 0) {
67 		FAIL("Could not start scanning (err %d)\n", err);
68 		return;
69 	}
70 
71 	printk("Waiting for connect\n");
72 	WAIT_FOR_FLAG(flag_connected);
73 
74 	printk("Raising security\n");
75 	err = bt_conn_set_security(default_conn, BT_SECURITY_L2);
76 	if (err) {
77 		FAIL("Failed to ser security level %d (err %d)\n", BT_SECURITY_L2, err);
78 		return;
79 	}
80 
81 	printk("Starting Discovery\n");
82 	bt_csip_set_coordinator_discover(default_conn);
83 	WAIT_FOR_FLAG(flag_csip_set_lock_discovered);
84 
85 	printk("Waiting for all notifications to be received\n");
86 
87 	WAIT_FOR_FLAG(flag_all_notifications_received);
88 
89 	/* Disconnect and wait for server to advertise again (after notifications are triggered) */
90 	bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
91 	UNSET_FLAG(flag_all_notifications_received);
92 	UNSET_FLAG(flag_csip_set_lock_discovered);
93 
94 	printk("Waiting for disconnect\n");
95 	WAIT_FOR_UNSET_FLAG(flag_connected);
96 
97 	printk("Starting scan\n");
98 	err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL);
99 	if (err != 0) {
100 		FAIL("Could not start scanning (err %d)\n", err);
101 		return;
102 	}
103 
104 	printk("Waiting for reconnect\n");
105 	WAIT_FOR_FLAG(flag_connected);
106 
107 	printk("Raising security\n");
108 	err = bt_conn_set_security(default_conn, BT_SECURITY_L2);
109 	if (err) {
110 		FAIL("Failed to ser security level %d (err %d)\n", BT_SECURITY_L2, err);
111 		return;
112 	}
113 
114 	printk("Starting Discovery\n");
115 	bt_csip_set_coordinator_discover(default_conn);
116 	WAIT_FOR_FLAG(flag_csip_set_lock_discovered);
117 
118 	printk("Waiting for all notifications to be received\n");
119 	WAIT_FOR_FLAG(flag_all_notifications_received);
120 
121 	bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
122 	WAIT_FOR_UNSET_FLAG(flag_connected);
123 
124 	PASS("CSIP Notify client Passed\n");
125 }
126 
127 static const struct bst_test_instance test_csip_notify_client[] = {
128 	{
129 		.test_id = "csip_notify_client",
130 		.test_pre_init_f = test_init,
131 		.test_tick_f = test_tick,
132 		.test_main_f = test_main,
133 	},
134 	BSTEST_END_MARKER,
135 };
136 
test_csip_notify_client_install(struct bst_test_list * tests)137 struct bst_test_list *test_csip_notify_client_install(struct bst_test_list *tests)
138 {
139 	return bst_add_tests(tests, test_csip_notify_client);
140 }
141