1 /*
2  * Copyright (c) 2022 Codecoup
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <stdbool.h>
7 #include <stddef.h>
8 #include <stdint.h>
9 
10 #include <zephyr/autoconf.h>
11 #include <zephyr/bluetooth/audio/has.h>
12 #include <zephyr/bluetooth/bluetooth.h>
13 #include <zephyr/bluetooth/gatt.h>
14 #include <zephyr/logging/log.h>
15 #include <zephyr/logging/log_core.h>
16 #include <zephyr/sys/util_macro.h>
17 
18 #include "bstests.h"
19 #include "common.h"
20 
21 LOG_MODULE_REGISTER(has_test, LOG_LEVEL_DBG);
22 
23 extern enum bst_result_t bst_result;
24 
25 const uint8_t test_preset_index_1 = 0x01;
26 const uint8_t test_preset_index_3 = 0x03;
27 const uint8_t test_preset_index_5 = 0x05;
28 const char *test_preset_name_1 = "test_preset_name_1";
29 const char *test_preset_name_3 = "test_preset_name_3";
30 const char *test_preset_name_5 = "test_preset_name_5";
31 const enum bt_has_properties test_preset_properties = BT_HAS_PROP_AVAILABLE;
32 
preset_select(uint8_t index,bool sync)33 static int preset_select(uint8_t index, bool sync)
34 {
35 	return 0;
36 }
37 
38 static const struct bt_has_preset_ops preset_ops = {
39 	.select = preset_select,
40 };
41 
start_adv(void)42 static void start_adv(void)
43 {
44 	int err;
45 
46 	err = bt_le_adv_start(BT_LE_ADV_CONN_ONE_TIME, ad, AD_SIZE, NULL, 0);
47 	if (err) {
48 		FAIL("Advertising failed to start (err %d)\n", err);
49 		return;
50 	}
51 
52 	LOG_DBG("Advertising successfully started");
53 }
54 
test_common(void)55 static void test_common(void)
56 {
57 	struct bt_has_features_param has_param = {0};
58 	struct bt_has_preset_register_param preset_param;
59 
60 	int err;
61 
62 	err = bt_enable(NULL);
63 	if (err) {
64 		FAIL("Bluetooth enable failed (err %d)\n", err);
65 		return;
66 	}
67 
68 	LOG_DBG("Bluetooth initialized");
69 
70 	start_adv();
71 
72 	has_param.type = BT_HAS_HEARING_AID_TYPE_BINAURAL;
73 	has_param.preset_sync_support = true;
74 
75 	err = bt_has_register(&has_param);
76 	if (err) {
77 		FAIL("HAS register failed (err %d)\n", err);
78 		return;
79 	}
80 
81 	has_param.type = BT_HAS_HEARING_AID_TYPE_MONAURAL;
82 	has_param.preset_sync_support = false;
83 
84 	err = bt_has_features_set(&has_param);
85 	if (err) {
86 		FAIL("HAS register failed (err %d)\n", err);
87 		return;
88 	}
89 
90 	preset_param.index = test_preset_index_5;
91 	preset_param.properties = test_preset_properties;
92 	preset_param.name = test_preset_name_5;
93 	preset_param.ops = &preset_ops,
94 
95 	err = bt_has_preset_register(&preset_param);
96 	if (err) {
97 		FAIL("Preset register failed (err %d)\n", err);
98 		return;
99 	}
100 
101 	preset_param.index = test_preset_index_1;
102 	preset_param.properties = test_preset_properties;
103 	preset_param.name = test_preset_name_1;
104 
105 	err = bt_has_preset_register(&preset_param);
106 	if (err) {
107 		FAIL("Preset register failed (err %d)\n", err);
108 		return;
109 	}
110 
111 	LOG_DBG("Presets registered");
112 
113 	PASS("HAS passed\n");
114 }
115 
test_main(void)116 static void test_main(void)
117 {
118 	test_common();
119 
120 	PASS("HAS passed\n");
121 }
122 
test_offline_behavior(void)123 static void test_offline_behavior(void)
124 {
125 	struct bt_has_preset_register_param preset_param;
126 	struct bt_has_features_param has_param = {0};
127 	int err;
128 
129 	test_common();
130 
131 	WAIT_FOR_FLAG(flag_connected);
132 	WAIT_FOR_UNSET_FLAG(flag_connected);
133 	start_adv();
134 
135 	preset_param.index = test_preset_index_3;
136 	preset_param.properties = test_preset_properties;
137 	preset_param.name = test_preset_name_3;
138 	preset_param.ops = &preset_ops,
139 
140 	err = bt_has_preset_register(&preset_param);
141 	if (err) {
142 		FAIL("Preset register failed (err %d)\n", err);
143 		return;
144 	}
145 
146 	has_param.type = BT_HAS_HEARING_AID_TYPE_BINAURAL;
147 	has_param.preset_sync_support = true;
148 
149 	err = bt_has_features_set(&has_param);
150 	if (err) {
151 		FAIL("Features set failed (err %d)\n", err);
152 		return;
153 	}
154 
155 	err = bt_has_preset_active_set(test_preset_index_3);
156 	if (err) {
157 		FAIL("Preset activation failed (err %d)\n", err);
158 		return;
159 	}
160 
161 	WAIT_FOR_FLAG(flag_connected);
162 
163 	PASS("HAS passed\n");
164 }
165 
166 static const struct bst_test_instance test_has[] = {
167 	{
168 		.test_id = "has",
169 		.test_pre_init_f = test_init,
170 		.test_tick_f = test_tick,
171 		.test_main_f = test_main,
172 	},
173 	{
174 		.test_id = "has_offline_behavior",
175 		.test_pre_init_f = test_init,
176 		.test_tick_f = test_tick,
177 		.test_main_f = test_offline_behavior,
178 	},
179 	BSTEST_END_MARKER,
180 };
181 
test_has_install(struct bst_test_list * tests)182 struct bst_test_list *test_has_install(struct bst_test_list *tests)
183 {
184 	if (IS_ENABLED(CONFIG_BT_HAS)) {
185 		return bst_add_tests(tests, test_has);
186 	} else {
187 		return tests;
188 	}
189 }
190