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