1 /*
2 * Copyright (c) 2023 Demant A/S
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <errno.h>
7 #include <stdint.h>
8 #include <string.h>
9
10 #include <zephyr/bluetooth/att.h>
11 #include <zephyr/bluetooth/bluetooth.h>
12 #include <zephyr/bluetooth/conn.h>
13 #include <zephyr/bluetooth/gatt.h>
14
15 #include "bstests.h"
16 #include "common.h"
17 #include "common/bt_str.h"
18
19 #include <zephyr/bluetooth/hci_types.h>
20 #include <zephyr/bluetooth/uuid.h>
21 #include <zephyr/logging/log.h>
22 #include <zephyr/logging/log_core.h>
23 #include <zephyr/sys/__assert.h>
24 #include <zephyr/sys/util_macro.h>
25 LOG_MODULE_REGISTER(pacs_notify_client_test, LOG_LEVEL_DBG);
26
27 struct pacs_instance_t {
28 uint16_t start_handle;
29 uint16_t end_handle;
30
31 struct bt_gatt_subscribe_params sink_pacs_sub;
32 struct bt_gatt_subscribe_params source_pacs_sub;
33 struct bt_gatt_subscribe_params sink_loc_sub;
34 struct bt_gatt_subscribe_params source_loc_sub;
35 struct bt_gatt_subscribe_params available_contexts_sub;
36 struct bt_gatt_subscribe_params supported_contexts_sub;
37
38 struct bt_gatt_discover_params discover_params;
39
40 int notify_received_mask;
41 };
42
43 extern enum bst_result_t bst_result;
44
45 CREATE_FLAG(flag_pacs_snk_discovered);
46 CREATE_FLAG(flag_pacs_src_discovered);
47 CREATE_FLAG(flag_snk_loc_discovered);
48 CREATE_FLAG(flag_src_loc_discovered);
49 CREATE_FLAG(flag_available_contexts_discovered);
50 CREATE_FLAG(flag_supported_contexts_discovered);
51 CREATE_FLAG(flag_all_notifications_received);
52 CREATE_FLAG(flag_available_contexts_received);
53
54 static struct bt_uuid_16 uuid = BT_UUID_INIT_16(0);
55
56 static struct pacs_instance_t pacs_instance;
57
pacs_notify_handler(struct bt_conn * conn,struct bt_gatt_subscribe_params * params,const void * data,uint16_t length)58 static uint8_t pacs_notify_handler(struct bt_conn *conn,
59 struct bt_gatt_subscribe_params *params,
60 const void *data, uint16_t length)
61 {
62 LOG_DBG("%p", params);
63
64 if (params == &pacs_instance.sink_pacs_sub) {
65 LOG_DBG("Received sink_pacs_sub notification");
66 pacs_instance.notify_received_mask |= BIT(0);
67 } else if (params == &pacs_instance.source_pacs_sub) {
68 LOG_DBG("Received source_pacs_sub notification");
69 pacs_instance.notify_received_mask |= BIT(1);
70 } else if (params == &pacs_instance.sink_loc_sub) {
71 LOG_DBG("Received sink_loc_sub notification");
72 pacs_instance.notify_received_mask |= BIT(2);
73 } else if (params == &pacs_instance.source_loc_sub) {
74 LOG_DBG("Received source_loc_sub notification");
75 pacs_instance.notify_received_mask |= BIT(3);
76 } else if (params == &pacs_instance.available_contexts_sub) {
77 LOG_DBG("Received available_contexts_sub notification");
78 pacs_instance.notify_received_mask |= BIT(4);
79 SET_FLAG(flag_available_contexts_received);
80 } else if (params == &pacs_instance.supported_contexts_sub) {
81 LOG_DBG("Received supported_contexts_sub notification");
82 pacs_instance.notify_received_mask |= BIT(5);
83 }
84
85 LOG_DBG("pacs_instance.notify_received_mask is %d", pacs_instance.notify_received_mask);
86
87 if (pacs_instance.notify_received_mask ==
88 (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5))) {
89 pacs_instance.notify_received_mask = 0;
90 SET_FLAG(flag_all_notifications_received);
91 }
92
93 return BT_GATT_ITER_CONTINUE;
94 }
95
discover_supported_contexts(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)96 static uint8_t discover_supported_contexts(struct bt_conn *conn, const struct bt_gatt_attr *attr,
97 struct bt_gatt_discover_params *params)
98 {
99 struct bt_gatt_subscribe_params *subscribe_params;
100 int err;
101
102 if (!attr) {
103 LOG_DBG("Discover complete");
104 (void)memset(params, 0, sizeof(*params));
105 return BT_GATT_ITER_STOP;
106 }
107
108 if (!bt_uuid_cmp(params->uuid, BT_UUID_PACS_SUPPORTED_CONTEXT)) {
109 LOG_DBG("PACS Supported Contexts Characteristic handle at %d", attr->handle);
110 subscribe_params = &pacs_instance.supported_contexts_sub;
111 memcpy(&uuid, BT_UUID_GATT_CCC, sizeof(uuid));
112 pacs_instance.discover_params.uuid = &uuid.uuid;
113 pacs_instance.discover_params.start_handle = attr->handle + 2;
114 pacs_instance.discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
115 subscribe_params->value_handle = bt_gatt_attr_value_handle(attr);
116
117 err = bt_gatt_discover(conn, &pacs_instance.discover_params);
118 if (err) {
119 LOG_DBG("Discover failed (err %d)", err);
120 }
121 } else if (!bt_uuid_cmp(params->uuid, BT_UUID_GATT_CCC)) {
122 LOG_DBG("CCC handle at %d", attr->handle);
123 subscribe_params = &pacs_instance.supported_contexts_sub;
124 subscribe_params->notify = pacs_notify_handler;
125 subscribe_params->value = BT_GATT_CCC_NOTIFY;
126 subscribe_params->ccc_handle = attr->handle;
127
128 err = bt_gatt_subscribe(conn, subscribe_params);
129 if (err && err != -EALREADY) {
130 LOG_DBG("Subscribe failed (err %d)", err);
131 } else {
132 SET_FLAG(flag_supported_contexts_discovered);
133 LOG_DBG("[SUBSCRIBED]");
134 }
135 } else {
136 LOG_DBG("Unknown handle at %d", attr->handle);
137 return BT_GATT_ITER_CONTINUE;
138 }
139
140 return BT_GATT_ITER_STOP;
141 }
142
discover_and_subscribe_supported_contexts(void)143 static void discover_and_subscribe_supported_contexts(void)
144 {
145 int err = 0;
146
147 LOG_DBG("");
148
149 memcpy(&uuid, BT_UUID_PACS_SUPPORTED_CONTEXT, sizeof(uuid));
150 pacs_instance.discover_params.uuid = &uuid.uuid;
151 pacs_instance.discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
152 pacs_instance.discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
153 pacs_instance.discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
154 pacs_instance.discover_params.func = discover_supported_contexts;
155
156 err = bt_gatt_discover(default_conn, &pacs_instance.discover_params);
157 if (err != 0) {
158 FAIL("Service Discovery failed (err %d)", err);
159 return;
160 }
161 }
162
discover_available_contexts(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)163 static uint8_t discover_available_contexts(struct bt_conn *conn, const struct bt_gatt_attr *attr,
164 struct bt_gatt_discover_params *params)
165 {
166 struct bt_gatt_subscribe_params *subscribe_params;
167 int err;
168
169 if (!attr) {
170 LOG_DBG("Discover complete");
171 (void)memset(params, 0, sizeof(*params));
172 return BT_GATT_ITER_STOP;
173 }
174
175 if (!bt_uuid_cmp(params->uuid, BT_UUID_PACS_AVAILABLE_CONTEXT)) {
176 LOG_DBG("PACS Available Contexts Characteristic handle at %d", attr->handle);
177 subscribe_params = &pacs_instance.available_contexts_sub;
178 memcpy(&uuid, BT_UUID_GATT_CCC, sizeof(uuid));
179 pacs_instance.discover_params.uuid = &uuid.uuid;
180 pacs_instance.discover_params.start_handle = attr->handle + 2;
181 pacs_instance.discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
182 subscribe_params->value_handle = bt_gatt_attr_value_handle(attr);
183
184 err = bt_gatt_discover(conn, &pacs_instance.discover_params);
185 if (err) {
186 LOG_DBG("Discover failed (err %d)", err);
187 }
188 } else if (!bt_uuid_cmp(params->uuid, BT_UUID_GATT_CCC)) {
189 LOG_DBG("CCC handle at %d", attr->handle);
190 subscribe_params = &pacs_instance.available_contexts_sub;
191 subscribe_params->notify = pacs_notify_handler;
192 subscribe_params->value = BT_GATT_CCC_NOTIFY;
193 subscribe_params->ccc_handle = attr->handle;
194
195 err = bt_gatt_subscribe(conn, subscribe_params);
196 if (err && err != -EALREADY) {
197 LOG_DBG("Subscribe failed (err %d)", err);
198 } else {
199 SET_FLAG(flag_available_contexts_discovered);
200 LOG_DBG("[SUBSCRIBED]");
201 }
202 } else {
203 LOG_DBG("Unknown handle at %d", attr->handle);
204 return BT_GATT_ITER_CONTINUE;
205 }
206
207 return BT_GATT_ITER_STOP;
208 }
209
discover_and_subscribe_available_contexts(void)210 static void discover_and_subscribe_available_contexts(void)
211 {
212 int err = 0;
213
214 LOG_DBG("");
215
216 memcpy(&uuid, BT_UUID_PACS_AVAILABLE_CONTEXT, sizeof(uuid));
217 pacs_instance.discover_params.uuid = &uuid.uuid;
218 pacs_instance.discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
219 pacs_instance.discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
220 pacs_instance.discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
221 pacs_instance.discover_params.func = discover_available_contexts;
222
223 err = bt_gatt_discover(default_conn, &pacs_instance.discover_params);
224 if (err != 0) {
225 FAIL("Service Discovery failed (err %d)", err);
226 return;
227 }
228 }
229
discover_src_loc(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)230 static uint8_t discover_src_loc(struct bt_conn *conn, const struct bt_gatt_attr *attr,
231 struct bt_gatt_discover_params *params)
232 {
233 struct bt_gatt_subscribe_params *subscribe_params;
234 int err;
235
236 if (!attr) {
237 LOG_DBG("Discover complete");
238 (void)memset(params, 0, sizeof(*params));
239 return BT_GATT_ITER_STOP;
240 }
241
242 if (!bt_uuid_cmp(params->uuid, BT_UUID_PACS_SRC_LOC)) {
243 LOG_DBG("PACS Source Location Characteristic handle at %d", attr->handle);
244 subscribe_params = &pacs_instance.source_loc_sub;
245 memcpy(&uuid, BT_UUID_GATT_CCC, sizeof(uuid));
246 pacs_instance.discover_params.uuid = &uuid.uuid;
247 pacs_instance.discover_params.start_handle = attr->handle + 2;
248 pacs_instance.discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
249 subscribe_params->value_handle = bt_gatt_attr_value_handle(attr);
250
251 err = bt_gatt_discover(conn, &pacs_instance.discover_params);
252 if (err) {
253 LOG_DBG("Discover failed (err %d)", err);
254 }
255 } else if (!bt_uuid_cmp(params->uuid, BT_UUID_GATT_CCC)) {
256 LOG_DBG("CCC handle at %d", attr->handle);
257 subscribe_params = &pacs_instance.source_loc_sub;
258 subscribe_params->notify = pacs_notify_handler;
259 subscribe_params->value = BT_GATT_CCC_NOTIFY;
260 subscribe_params->ccc_handle = attr->handle;
261
262 err = bt_gatt_subscribe(conn, subscribe_params);
263 if (err && err != -EALREADY) {
264 LOG_DBG("Subscribe failed (err %d)", err);
265 } else {
266 SET_FLAG(flag_src_loc_discovered);
267 LOG_DBG("[SUBSCRIBED]");
268 }
269 } else {
270 LOG_DBG("Unknown handle at %d", attr->handle);
271 return BT_GATT_ITER_CONTINUE;
272 }
273
274 return BT_GATT_ITER_STOP;
275 }
276
discover_and_subscribe_src_loc(void)277 static void discover_and_subscribe_src_loc(void)
278 {
279 int err = 0;
280
281 LOG_DBG("");
282
283 memcpy(&uuid, BT_UUID_PACS_SRC_LOC, sizeof(uuid));
284 pacs_instance.discover_params.uuid = &uuid.uuid;
285 pacs_instance.discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
286 pacs_instance.discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
287 pacs_instance.discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
288 pacs_instance.discover_params.func = discover_src_loc;
289
290 err = bt_gatt_discover(default_conn, &pacs_instance.discover_params);
291 if (err != 0) {
292 FAIL("Service Discovery failed (err %d)", err);
293 return;
294 }
295 }
296
discover_snk_loc(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)297 static uint8_t discover_snk_loc(struct bt_conn *conn, const struct bt_gatt_attr *attr,
298 struct bt_gatt_discover_params *params)
299 {
300 struct bt_gatt_subscribe_params *subscribe_params;
301 int err;
302
303 if (!attr) {
304 LOG_DBG("Discover complete");
305 (void)memset(params, 0, sizeof(*params));
306 return BT_GATT_ITER_STOP;
307 }
308
309 if (!bt_uuid_cmp(params->uuid, BT_UUID_PACS_SNK_LOC)) {
310 LOG_DBG("PACS Sink Location Characteristic handle at %d", attr->handle);
311 subscribe_params = &pacs_instance.sink_loc_sub;
312 memcpy(&uuid, BT_UUID_GATT_CCC, sizeof(uuid));
313 pacs_instance.discover_params.uuid = &uuid.uuid;
314 pacs_instance.discover_params.start_handle = attr->handle + 2;
315 pacs_instance.discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
316 subscribe_params->value_handle = bt_gatt_attr_value_handle(attr);
317
318 err = bt_gatt_discover(conn, &pacs_instance.discover_params);
319 if (err) {
320 LOG_DBG("Discover failed (err %d)", err);
321 }
322 } else if (!bt_uuid_cmp(params->uuid, BT_UUID_GATT_CCC)) {
323 LOG_DBG("CCC handle at %d", attr->handle);
324 subscribe_params = &pacs_instance.sink_loc_sub;
325 subscribe_params->notify = pacs_notify_handler;
326 subscribe_params->value = BT_GATT_CCC_NOTIFY;
327 subscribe_params->ccc_handle = attr->handle;
328
329 err = bt_gatt_subscribe(conn, subscribe_params);
330 if (err && err != -EALREADY) {
331 LOG_DBG("Subscribe failed (err %d)", err);
332 } else {
333 SET_FLAG(flag_snk_loc_discovered);
334 LOG_DBG("[SUBSCRIBED]");
335 }
336 } else {
337 LOG_DBG("Unknown handle at %d", attr->handle);
338 return BT_GATT_ITER_CONTINUE;
339 }
340
341 return BT_GATT_ITER_STOP;
342 }
343
discover_and_subscribe_snk_loc(void)344 static void discover_and_subscribe_snk_loc(void)
345 {
346 int err = 0;
347
348 LOG_DBG("");
349
350 memcpy(&uuid, BT_UUID_PACS_SNK_LOC, sizeof(uuid));
351 pacs_instance.discover_params.uuid = &uuid.uuid;
352 pacs_instance.discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
353 pacs_instance.discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
354 pacs_instance.discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
355 pacs_instance.discover_params.func = discover_snk_loc;
356
357 err = bt_gatt_discover(default_conn, &pacs_instance.discover_params);
358 if (err != 0) {
359 FAIL("Service Discovery failed (err %d)", err);
360 return;
361 }
362 }
363
discover_pacs_src(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)364 static uint8_t discover_pacs_src(struct bt_conn *conn, const struct bt_gatt_attr *attr,
365 struct bt_gatt_discover_params *params)
366 {
367 struct bt_gatt_subscribe_params *subscribe_params;
368 int err;
369
370 if (!attr) {
371 LOG_DBG("Discover complete");
372 (void)memset(params, 0, sizeof(*params));
373 return BT_GATT_ITER_STOP;
374 }
375
376 if (!bt_uuid_cmp(params->uuid, BT_UUID_PACS_SRC)) {
377 LOG_DBG("PACS Source Characteristic handle at %d", attr->handle);
378 subscribe_params = &pacs_instance.source_pacs_sub;
379 memcpy(&uuid, BT_UUID_GATT_CCC, sizeof(uuid));
380 pacs_instance.discover_params.uuid = &uuid.uuid;
381 pacs_instance.discover_params.start_handle = attr->handle + 2;
382 pacs_instance.discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
383 subscribe_params->value_handle = bt_gatt_attr_value_handle(attr);
384
385 err = bt_gatt_discover(conn, &pacs_instance.discover_params);
386 if (err) {
387 LOG_DBG("Discover failed (err %d)", err);
388 }
389 } else if (!bt_uuid_cmp(params->uuid, BT_UUID_GATT_CCC)) {
390 LOG_DBG("CCC handle at %d", attr->handle);
391 subscribe_params = &pacs_instance.source_pacs_sub;
392 subscribe_params->notify = pacs_notify_handler;
393 subscribe_params->value = BT_GATT_CCC_NOTIFY;
394 subscribe_params->ccc_handle = attr->handle;
395
396 err = bt_gatt_subscribe(conn, subscribe_params);
397 if (err && err != -EALREADY) {
398 LOG_DBG("Subscribe failed (err %d)", err);
399 } else {
400 SET_FLAG(flag_pacs_src_discovered);
401 LOG_DBG("[SUBSCRIBED]");
402 }
403 } else {
404 LOG_DBG("Unknown handle at %d", attr->handle);
405 return BT_GATT_ITER_CONTINUE;
406 }
407
408 return BT_GATT_ITER_STOP;
409 }
410
discover_and_subscribe_src_pacs(void)411 static void discover_and_subscribe_src_pacs(void)
412 {
413 int err = 0;
414
415 LOG_DBG("");
416
417 memcpy(&uuid, BT_UUID_PACS_SRC, sizeof(uuid));
418 pacs_instance.discover_params.uuid = &uuid.uuid;
419 pacs_instance.discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
420 pacs_instance.discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
421 pacs_instance.discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
422 pacs_instance.discover_params.func = discover_pacs_src;
423
424 err = bt_gatt_discover(default_conn, &pacs_instance.discover_params);
425 if (err != 0) {
426 FAIL("Service Discovery failed (err %d)", err);
427 return;
428 }
429 }
430
discover_pacs_snk(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)431 static uint8_t discover_pacs_snk(struct bt_conn *conn, const struct bt_gatt_attr *attr,
432 struct bt_gatt_discover_params *params)
433 {
434 struct bt_gatt_subscribe_params *subscribe_params;
435 int err;
436
437 if (!attr) {
438 LOG_DBG("Discover complete");
439 (void)memset(params, 0, sizeof(*params));
440 return BT_GATT_ITER_STOP;
441 }
442
443 if (!bt_uuid_cmp(params->uuid, BT_UUID_PACS_SNK)) {
444 LOG_DBG("PACS Sink Characteristic handle at %d", attr->handle);
445 subscribe_params = &pacs_instance.sink_pacs_sub;
446 memcpy(&uuid, BT_UUID_GATT_CCC, sizeof(uuid));
447 pacs_instance.discover_params.uuid = &uuid.uuid;
448 pacs_instance.discover_params.start_handle = attr->handle + 2;
449 pacs_instance.discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
450 subscribe_params->value_handle = bt_gatt_attr_value_handle(attr);
451
452 err = bt_gatt_discover(conn, &pacs_instance.discover_params);
453 if (err) {
454 LOG_DBG("Discover failed (err %d)", err);
455 }
456 } else if (!bt_uuid_cmp(params->uuid, BT_UUID_GATT_CCC)) {
457 LOG_DBG("CCC handle at %d", attr->handle);
458 subscribe_params = &pacs_instance.sink_pacs_sub;
459 subscribe_params->notify = pacs_notify_handler;
460 subscribe_params->value = BT_GATT_CCC_NOTIFY;
461 subscribe_params->ccc_handle = attr->handle;
462
463 err = bt_gatt_subscribe(conn, subscribe_params);
464 if (err && err != -EALREADY) {
465 LOG_DBG("Subscribe failed (err %d)", err);
466 } else {
467 SET_FLAG(flag_pacs_snk_discovered);
468 LOG_DBG("[SUBSCRIBED]");
469 }
470 } else {
471 LOG_DBG("Unknown handle at %d", attr->handle);
472 return BT_GATT_ITER_CONTINUE;
473 }
474
475 return BT_GATT_ITER_STOP;
476 }
477
discover_and_subscribe_snk_pacs(void)478 static void discover_and_subscribe_snk_pacs(void)
479 {
480 int err = 0;
481
482 LOG_DBG("");
483
484 memcpy(&uuid, BT_UUID_PACS_SNK, sizeof(uuid));
485 pacs_instance.discover_params.uuid = &uuid.uuid;
486 pacs_instance.discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
487 pacs_instance.discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
488 pacs_instance.discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
489 pacs_instance.discover_params.func = discover_pacs_snk;
490
491 err = bt_gatt_discover(default_conn, &pacs_instance.discover_params);
492 if (err != 0) {
493 FAIL("Service Discovery failed (err %d)", err);
494 return;
495 }
496 }
497
test_main(void)498 static void test_main(void)
499 {
500 int err;
501
502 LOG_DBG("Enabling Bluetooth");
503 err = bt_enable(NULL);
504 if (err != 0) {
505 FAIL("Bluetooth enable failed (err %d)", err);
506 return;
507 }
508
509 bt_le_scan_cb_register(&common_scan_cb);
510
511 LOG_DBG("Starting scan");
512 err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL);
513 if (err != 0) {
514 FAIL("Could not start scanning (err %d)", err);
515 return;
516 }
517
518 WAIT_FOR_FLAG(flag_connected);
519
520 LOG_DBG("Raising security");
521 err = bt_conn_set_security(default_conn, BT_SECURITY_L2);
522 if (err) {
523 FAIL("Failed to ser security level %d (err %d)", BT_SECURITY_L2, err);
524 return;
525 }
526
527 LOG_DBG("Starting Discovery");
528
529 discover_and_subscribe_snk_pacs();
530 WAIT_FOR_FLAG(flag_pacs_snk_discovered);
531
532 discover_and_subscribe_snk_loc();
533 WAIT_FOR_FLAG(flag_snk_loc_discovered);
534
535 discover_and_subscribe_src_pacs();
536 WAIT_FOR_FLAG(flag_pacs_src_discovered);
537
538 discover_and_subscribe_src_loc();
539 WAIT_FOR_FLAG(flag_src_loc_discovered);
540
541 discover_and_subscribe_available_contexts();
542 WAIT_FOR_FLAG(flag_available_contexts_discovered);
543
544 discover_and_subscribe_supported_contexts();
545 WAIT_FOR_FLAG(flag_supported_contexts_discovered);
546
547 LOG_DBG("Waiting for all notifications to be received");
548
549 WAIT_FOR_FLAG(flag_all_notifications_received);
550
551 /* Disconnect and wait for server to advertise again (after notifications are triggered) */
552 UNSET_FLAG(flag_all_notifications_received);
553 err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
554 __ASSERT_NO_MSG(err == 0);
555 WAIT_FOR_UNSET_FLAG(flag_connected);
556
557 LOG_DBG("Starting scan");
558 err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL);
559 if (err != 0) {
560 FAIL("Could not start scanning (err %d)", err);
561 return;
562 }
563
564 WAIT_FOR_FLAG(flag_connected);
565
566 LOG_DBG("Raising security");
567 err = bt_conn_set_security(default_conn, BT_SECURITY_L2);
568 if (err) {
569 FAIL("Failed to ser security level %d (err %d)", BT_SECURITY_L2, err);
570 return;
571 }
572
573 LOG_DBG("Waiting for all notifications to be received");
574 WAIT_FOR_FLAG(flag_all_notifications_received);
575
576 err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
577 __ASSERT_NO_MSG(err == 0);
578 WAIT_FOR_UNSET_FLAG(flag_connected);
579 UNSET_FLAG(flag_available_contexts_received);
580
581 LOG_DBG("Starting scan");
582 err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL);
583 if (err != 0) {
584 FAIL("Could not start scanning (err %d)", err);
585 return;
586 }
587
588 WAIT_FOR_FLAG(flag_connected);
589
590 LOG_DBG("Raising security");
591 err = bt_conn_set_security(default_conn, BT_SECURITY_L2);
592 if (err) {
593 FAIL("Failed to ser security level %d (err %d)", BT_SECURITY_L2, err);
594 return;
595 }
596
597 LOG_DBG("Waiting for available contexts notification to be received");
598 WAIT_FOR_FLAG(flag_available_contexts_received);
599
600 err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
601 __ASSERT_NO_MSG(err == 0);
602 WAIT_FOR_UNSET_FLAG(flag_connected);
603 UNSET_FLAG(flag_available_contexts_received);
604
605 LOG_DBG("Starting scan");
606 err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL);
607 if (err != 0) {
608 FAIL("Could not start scanning (err %d)", err);
609 return;
610 }
611
612 WAIT_FOR_FLAG(flag_connected);
613
614 LOG_DBG("Raising security");
615 err = bt_conn_set_security(default_conn, BT_SECURITY_L2);
616 if (err) {
617 FAIL("Failed to ser security level %d (err %d)", BT_SECURITY_L2, err);
618 return;
619 }
620
621 LOG_DBG("Waiting for available contexts notification to be received");
622 WAIT_FOR_FLAG(flag_available_contexts_received);
623
624 err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
625 __ASSERT_NO_MSG(err == 0);
626 WAIT_FOR_UNSET_FLAG(flag_connected);
627
628 PASS("GATT client Passed\n");
629 }
630
631 static const struct bst_test_instance test_pacs_notify_client[] = {
632 {
633 .test_id = "pacs_notify_client",
634 .test_pre_init_f = test_init,
635 .test_tick_f = test_tick,
636 .test_main_f = test_main,
637 },
638 BSTEST_END_MARKER,
639 };
640
test_pacs_notify_client_install(struct bst_test_list * tests)641 struct bst_test_list *test_pacs_notify_client_install(struct bst_test_list *tests)
642 {
643 return bst_add_tests(tests, test_pacs_notify_client);
644 }
645