1 /*
2 * Copyright (c) 2024 Demant A/S
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8
9 #include "bs_types.h"
10 #include "bs_tracing.h"
11 #include "time_machine.h"
12 #include "bstests.h"
13 #include <argparse.h>
14
15 #include <zephyr/types.h>
16 #include <stddef.h>
17 #include <errno.h>
18
19 #include <zephyr/bluetooth/services/bas.h>
20 #include <zephyr/bluetooth/bluetooth.h>
21 #include <zephyr/bluetooth/hci.h>
22 #include <zephyr/bluetooth/conn.h>
23 #include <zephyr/bluetooth/uuid.h>
24 #include <zephyr/bluetooth/gatt.h>
25 #include <zephyr/sys/byteorder.h>
26
27 #include "testlib/conn.h"
28 #include "testlib/scan.h"
29 #include "testlib/log_utils.h"
30
31 #include "babblekit/flags.h"
32 #include "babblekit/sync.h"
33 #include "babblekit/testcase.h"
34
35 #include <zephyr/logging/log.h>
36 LOG_MODULE_REGISTER(bt_bsim_bas, CONFIG_BT_BAS_LOG_LEVEL);
37
38 static struct bt_conn *default_conn;
39 static bt_addr_le_t peer = {};
40
41 static struct bt_uuid_16 uuid = BT_UUID_INIT_16(0);
42 static struct bt_gatt_discover_params discover_params;
43
44 static struct bt_gatt_subscribe_params battery_level_notify_params;
45 static struct bt_gatt_subscribe_params battery_level_status_sub_params;
46 static struct bt_gatt_subscribe_params battery_critical_status_sub_params;
47
48 /*
49 * Battery Service test:
50 * We expect to find a connectable peripheral to which we will
51 * connect and discover Battery Service
52 *
53 * Test the Read/Notify/Indicate Characteristics of BAS
54 */
55
56 #define WAIT_TIME 10 /*seconds*/
57 #define BAS_BLS_IND_RECEIVED_COUNT 20
58 #define BAS_BLS_NTF_RECEIVED_COUNT 20
59
60 static DEFINE_FLAG(notification_count_reached);
61 static DEFINE_FLAG(indication_count_reached);
62 static DEFINE_FLAG(bcs_char_read);
63
64 /* Callback for handling Battery Critical Status Read Response */
battery_critical_status_read_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)65 static uint8_t battery_critical_status_read_cb(struct bt_conn *conn, uint8_t err,
66 struct bt_gatt_read_params *params, const void *data,
67 uint16_t length)
68 {
69 TEST_ASSERT(err == 0, "Failed to read Battery critical status (err %d)", err);
70 TEST_ASSERT(length > 0, "No data is sent");
71
72 if (data) {
73 uint8_t status_byte = *(uint8_t *)data;
74
75 printk("[READ] BAS Critical Status:\n");
76 printk("Battery state: %s\n",
77 (status_byte & BT_BAS_BCS_BATTERY_CRITICAL_STATE) ? "Critical" : "Normal");
78 printk("Immediate service: %s\n",
79 (status_byte & BT_BAS_BCS_IMMEDIATE_SERVICE_REQUIRED) ? "Required"
80 : "Not Required");
81 }
82 SET_FLAG(bcs_char_read);
83 return BT_GATT_ITER_STOP;
84 }
85
86 static struct bt_gatt_read_params read_bcs_params = {
87 .func = battery_critical_status_read_cb,
88 .by_uuid.uuid = BT_UUID_BAS_BATTERY_CRIT_STATUS,
89 .by_uuid.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE,
90 .by_uuid.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE,
91 };
92
93 /* Callback for handling Battery Level Read Response */
battery_level_read_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)94 static uint8_t battery_level_read_cb(struct bt_conn *conn, uint8_t err,
95 struct bt_gatt_read_params *params, const void *data,
96 uint16_t length)
97 {
98 TEST_ASSERT(err == 0, "Failed to read Battery Level (err %d)", err);
99 if (data) {
100 LOG_DBG("[READ] BAS Battery Level: %d%%\n", *(const uint8_t *)data);
101 }
102
103 return BT_GATT_ITER_STOP;
104 }
105
106 static struct bt_gatt_read_params read_blvl_params = {
107 .func = battery_level_read_cb,
108 .by_uuid.uuid = BT_UUID_BAS_BATTERY_LEVEL_STATUS,
109 .by_uuid.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE,
110 .by_uuid.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE,
111 };
112
113 extern enum bst_result_t bst_result;
114
test_bas_central_init(void)115 static void test_bas_central_init(void)
116 {
117 bst_ticker_set_next_tick_absolute(WAIT_TIME * 1e6);
118 bst_result = In_progress;
119 }
120
test_bas_central_tick(bs_time_t HW_device_time)121 static void test_bas_central_tick(bs_time_t HW_device_time)
122 {
123 /*
124 * If in WAIT_TIME seconds the testcase did not already pass
125 * (and finish) we consider it failed
126 */
127 if (bst_result != Passed) {
128 TEST_FAIL("test_bas_central failed (not passed after %i seconds)\n", WAIT_TIME);
129 }
130 }
131
132 /* Callback for handling Battery Level Notifications */
battery_level_notify_cb(struct bt_conn * conn,struct bt_gatt_subscribe_params * params,const void * data,uint16_t length)133 static uint8_t battery_level_notify_cb(struct bt_conn *conn,
134 struct bt_gatt_subscribe_params *params, const void *data,
135 uint16_t length)
136 {
137 if (data) {
138 LOG_INF("[NOTIFICATION] BAS Battery Level: %d%%", *(const uint8_t *)data);
139 } else {
140 LOG_INF("Battery Level Notifications disabled");
141 }
142 return BT_GATT_ITER_CONTINUE;
143 }
144
parse_battery_level_status(const uint8_t * data,uint16_t length)145 static bool parse_battery_level_status(const uint8_t *data, uint16_t length)
146 {
147 /* Check minimum length for parsing flags and power state */
148 if (length < 3) {
149 TEST_FAIL("Invalid data length: %d", length);
150 return false;
151 }
152
153 /* Parse flags (first byte) */
154 uint8_t flags = data[0];
155
156 LOG_INF("Parsed Flags: 0x%02x", flags);
157
158 if (flags & BT_BAS_BLS_FLAG_IDENTIFIER_PRESENT) {
159 LOG_INF(" Identifier Present");
160 } else {
161 LOG_INF(" Identifier Not Present");
162 }
163
164 if (flags & BT_BAS_BLS_FLAG_BATTERY_LEVEL_PRESENT) {
165 LOG_INF(" Battery Level Present");
166 } else {
167 LOG_INF(" Battery Level Not Present");
168 }
169
170 if (flags & BT_BAS_BLS_FLAG_ADDITIONAL_STATUS_PRESENT) {
171 LOG_INF(" Additional Status Present");
172 } else {
173 LOG_INF(" Additional Status Not Present");
174 }
175
176 /* Parse power state (next 2 bytes) */
177 uint16_t power_state = sys_get_le16(&data[1]);
178
179 LOG_INF("Parsed Power State: 0x%04x", power_state);
180 /* Print out each power state value */
181 LOG_INF(" Battery Present: %s", (power_state & BIT(0)) ? "Yes" : "No");
182
183 uint8_t wired_power = (power_state >> 1) & 0x03;
184
185 switch (wired_power) {
186 case 0:
187 LOG_INF(" Wired Power Source: No");
188 break;
189 case 1:
190 LOG_INF(" Wired Power Source: Yes");
191 break;
192 case 2:
193 LOG_INF(" Wired Power Source: Unknown");
194 break;
195 default:
196 LOG_INF(" Wired Power Source: RFU");
197 break;
198 }
199
200 uint8_t wireless_power = (power_state >> 3) & 0x03;
201
202 switch (wireless_power) {
203 case 0:
204 LOG_INF(" Wireless Power Source: No");
205 break;
206 case 1:
207 LOG_INF(" Wireless Power Source: Yes");
208 break;
209 case 2:
210 LOG_INF(" Wireless Power Source: Unknown");
211 break;
212 default:
213 LOG_INF(" Wireless Power Source: RFU");
214 break;
215 }
216
217 uint8_t charge_state = (power_state >> 5) & 0x03;
218
219 switch (charge_state) {
220 case 0:
221 LOG_INF(" Battery Charge State: Unknown");
222 break;
223 case 1:
224 LOG_INF(" Battery Charge State: Charging");
225 break;
226 case 2:
227 LOG_INF(" Battery Charge State: Discharging (Active)");
228 break;
229 case 3:
230 LOG_INF(" Battery Charge State: Discharging (Inactive)");
231 break;
232 }
233
234 uint8_t charge_level = (power_state >> 7) & 0x03;
235
236 switch (charge_level) {
237 case 0:
238 LOG_INF(" Battery Charge Level: Unknown");
239 break;
240 case 1:
241 LOG_INF(" Battery Charge Level: Good");
242 break;
243 case 2:
244 LOG_INF(" Battery Charge Level: Low");
245 break;
246 case 3:
247 LOG_INF(" Battery Charge Level: Critical");
248 break;
249 }
250
251 uint8_t charging_type = (power_state >> 9) & 0x07;
252
253 switch (charging_type) {
254 case 0:
255 LOG_INF(" Charging Type: Unknown or Not Charging");
256 break;
257 case 1:
258 LOG_INF(" Charging Type: Constant Current");
259 break;
260 case 2:
261 LOG_INF(" Charging Type: Constant Voltage");
262 break;
263 case 3:
264 LOG_INF(" Charging Type: Trickle");
265 break;
266 case 4:
267 LOG_INF(" Charging Type: Float");
268 break;
269 default:
270 LOG_INF(" Charging Type: RFU");
271 break;
272 }
273
274 uint8_t charging_fault = (power_state >> 12) & 0x07;
275
276 if (charging_fault) {
277 LOG_INF(" Charging Fault Reason: %s%s%s",
278 (charging_fault & BIT(0)) ? "Battery " : "",
279 (charging_fault & BIT(1)) ? "External Power Source " : "",
280 (charging_fault & BIT(2)) ? "Other " : "");
281 } else {
282 LOG_INF(" Charging Fault Reason: None");
283 }
284
285 /* Optional: Check if identifier is present */
286 if (IS_ENABLED(CONFIG_BT_BAS_BLS_IDENTIFIER_PRESENT)) {
287 /* Check if length is sufficient for identifier */
288 if (length < 5) {
289 TEST_FAIL("Invalid data length for identifier");
290 return false;
291 }
292
293 /* Parse identifier (next 2 bytes) */
294 uint16_t identifier = sys_get_le16(&data[3]);
295
296 LOG_INF("Parsed Identifier: 0x%04x", identifier);
297 }
298
299 /* Optional: Check if battery level is present */
300 if (IS_ENABLED(CONFIG_BT_BAS_BLS_BATTERY_LEVEL_PRESENT)) {
301 /* Check if length is sufficient for battery level */
302 if (length < 6) {
303 TEST_FAIL("Invalid data length for battery level");
304 return false;
305 }
306
307 /* Parse battery level (next byte) */
308 uint8_t battery_level = data[5];
309
310 LOG_INF("Parsed Battery Level: %d%%", battery_level);
311 }
312
313 /* Optional: Check if additional status is present */
314 if (IS_ENABLED(CONFIG_BT_BAS_BLS_ADDITIONAL_STATUS_PRESENT)) {
315 /* Check if length is sufficient for additional status */
316 if (length < 7) {
317 TEST_FAIL("Invalid data length for additional status");
318 return false;
319 }
320
321 /* Parse additional status (next byte) */
322 uint8_t additional_status = data[6];
323
324 LOG_INF("Parsed Additional Status: 0x%02x", additional_status);
325
326 /* Print out additional status values */
327 uint8_t service_required = additional_status & 0x03;
328
329 switch (service_required) {
330 case 0:
331 LOG_INF(" Service Required: False");
332 break;
333 case 1:
334 LOG_INF(" Service Required: True");
335 break;
336 case 2:
337 LOG_INF(" Service Required: Unknown");
338 break;
339 default:
340 LOG_INF(" Service Required: RFU");
341 break;
342 }
343
344 bool battery_fault = (additional_status & BIT(2)) ? true : false;
345
346 LOG_INF(" Battery Fault: %s", battery_fault ? "Yes" : "No");
347 }
348
349 return true;
350 }
351
battery_critical_status_indicate_cb(struct bt_conn * conn,struct bt_gatt_subscribe_params * params,const void * data,uint16_t length)352 static unsigned char battery_critical_status_indicate_cb(struct bt_conn *conn,
353 struct bt_gatt_subscribe_params *params,
354 const void *data, uint16_t length)
355 {
356 if (!data) {
357 LOG_INF("BAS critical status indication disabled\n");
358 } else {
359 uint8_t status_byte = ((uint8_t *)data)[0];
360
361 printk("[INDICATION] BAS Critical Status:\n");
362 printk("Battery state: %s\n",
363 (status_byte & BT_BAS_BCS_BATTERY_CRITICAL_STATE) ? "Critical" : "Normal");
364 printk("Immediate service: %s\n",
365 (status_byte & BT_BAS_BCS_IMMEDIATE_SERVICE_REQUIRED) ? "Required"
366 : "Not Required");
367 }
368 return BT_GATT_ITER_CONTINUE;
369 }
370
battery_level_status_indicate_cb(struct bt_conn * conn,struct bt_gatt_subscribe_params * params,const void * data,uint16_t length)371 static unsigned char battery_level_status_indicate_cb(struct bt_conn *conn,
372 struct bt_gatt_subscribe_params *params,
373 const void *data, uint16_t length)
374 {
375 if (!data) {
376 LOG_INF("bas level status indication disabled\n");
377 } else {
378 static int ind_received;
379
380 printk("[INDICATION] BAS Battery Level Status: ");
381 for (int i = 0; i < length; i++) {
382 printk("%02x ", ((uint8_t *)data)[i]);
383 }
384 printk("\n");
385
386 if (parse_battery_level_status(data, length)) {
387 LOG_INF("Notification parsed successfully");
388 } else {
389 LOG_ERR("Notification parsing failed");
390 }
391
392 if (ind_received++ > BAS_BLS_IND_RECEIVED_COUNT) {
393 SET_FLAG(indication_count_reached);
394 }
395 }
396 return BT_GATT_ITER_CONTINUE;
397 }
398
battery_level_status_notify_cb(struct bt_conn * conn,struct bt_gatt_subscribe_params * params,const void * data,uint16_t length)399 static uint8_t battery_level_status_notify_cb(struct bt_conn *conn,
400 struct bt_gatt_subscribe_params *params,
401 const void *data, uint16_t length)
402 {
403 if (!data) {
404 LOG_INF("bas level status notification disabled\n");
405 } else {
406 static int notify_count;
407
408 printk("[NOTIFICATION] BAS Battery Level Status: ");
409 for (int i = 0; i < length; i++) {
410 printk("%02x ", ((uint8_t *)data)[i]);
411 }
412 printk("\n");
413
414 if (parse_battery_level_status(data, length)) {
415 LOG_INF("Notification parsed successfully");
416 } else {
417 LOG_ERR("Notification parsing failed");
418 }
419
420 if (notify_count++ > BAS_BLS_NTF_RECEIVED_COUNT) {
421 SET_FLAG(notification_count_reached);
422 }
423 }
424 return BT_GATT_ITER_CONTINUE;
425 }
426
subscribe_battery_level(const struct bt_gatt_attr * attr)427 static void subscribe_battery_level(const struct bt_gatt_attr *attr)
428 {
429 int err;
430 struct bt_gatt_attr *ccc_attr = bt_gatt_find_by_uuid(attr, 0, BT_UUID_GATT_CCC);
431
432 battery_level_notify_params = (struct bt_gatt_subscribe_params){
433 .ccc_handle = bt_gatt_attr_get_handle(ccc_attr),
434 .value_handle = bt_gatt_attr_value_handle(attr),
435 .value = BT_GATT_CCC_NOTIFY,
436 .notify = battery_level_notify_cb,
437 };
438
439 err = bt_gatt_subscribe(default_conn, &battery_level_notify_params);
440 if (err && err != -EALREADY) {
441 TEST_FAIL("Subscribe failed (err %d)\n", err);
442 } else {
443 LOG_DBG("Battery level [SUBSCRIBED]\n");
444 }
445
446 err = bt_gatt_read(default_conn, &read_blvl_params);
447 if (err != 0) {
448 TEST_FAIL("Battery Level Read failed (err %d)\n", err);
449 }
450 }
451
subscribe_battery_critical_status(const struct bt_gatt_attr * attr)452 static void subscribe_battery_critical_status(const struct bt_gatt_attr *attr)
453 {
454 int err;
455 struct bt_gatt_attr *ccc_attr = bt_gatt_find_by_uuid(attr, 0, BT_UUID_GATT_CCC);
456
457 battery_critical_status_sub_params = (struct bt_gatt_subscribe_params){
458 .ccc_handle = bt_gatt_attr_get_handle(ccc_attr),
459 .value_handle = bt_gatt_attr_value_handle(attr),
460 .value = BT_GATT_CCC_INDICATE,
461 .notify = battery_critical_status_indicate_cb,
462 };
463
464 err = bt_gatt_subscribe(default_conn, &battery_critical_status_sub_params);
465 if (err && err != -EALREADY) {
466 TEST_FAIL("Subscribe failed (err %d)\n", err);
467 } else {
468 LOG_DBG("Battery critical status [SUBSCRIBED]\n");
469 }
470
471 err = bt_gatt_read(default_conn, &read_bcs_params);
472 if (err != 0) {
473 TEST_FAIL("Battery Critical Status Read failed (err %d)\n", err);
474 }
475 }
476
subscribe_battery_level_status(const struct bt_gatt_attr * attr)477 static void subscribe_battery_level_status(const struct bt_gatt_attr *attr)
478 {
479 int err;
480 struct bt_gatt_attr *ccc_attr = bt_gatt_find_by_uuid(attr, 0, BT_UUID_GATT_CCC);
481
482 if (get_device_nbr() == 1) { /* One device for Indication */
483 battery_level_status_sub_params = (struct bt_gatt_subscribe_params){
484 .ccc_handle = bt_gatt_attr_get_handle(ccc_attr),
485 .value_handle = bt_gatt_attr_value_handle(attr),
486 .value = BT_GATT_CCC_INDICATE,
487 .notify = battery_level_status_indicate_cb,
488 };
489 } else { /* Other device for Notification */
490 battery_level_status_sub_params = (struct bt_gatt_subscribe_params){
491 .ccc_handle = bt_gatt_attr_get_handle(ccc_attr),
492 .value_handle = bt_gatt_attr_value_handle(attr),
493 .value = BT_GATT_CCC_NOTIFY,
494 .notify = battery_level_status_notify_cb,
495 };
496 }
497
498 err = bt_gatt_subscribe(default_conn, &battery_level_status_sub_params);
499 if (err && err != -EALREADY) {
500 TEST_FAIL("Subscribe failed (err %d)\n", err);
501 } else {
502 LOG_DBG("Battery level status [SUBSCRIBED]\n");
503 }
504 }
505
discover_func(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)506 static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *attr,
507 struct bt_gatt_discover_params *params)
508 {
509 int err;
510
511 if (!attr) {
512 LOG_DBG("Discover complete\n");
513 memset(params, 0, sizeof(*params));
514 return BT_GATT_ITER_STOP;
515 }
516
517 LOG_DBG("[ATTRIBUTE] handle %u\n", attr->handle);
518
519 if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_BAS)) {
520 LOG_DBG("Battery Service\n");
521 memcpy(&uuid, BT_UUID_BAS_BATTERY_LEVEL, sizeof(uuid));
522 discover_params.uuid = &uuid.uuid;
523 discover_params.start_handle = attr->handle + 1;
524 discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
525
526 err = bt_gatt_discover(conn, &discover_params);
527 if (err) {
528 TEST_FAIL("Discover failed (err %d)\n", err);
529 }
530
531 } else if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_BAS_BATTERY_LEVEL)) {
532 LOG_DBG("Subscribe Battery Level Char\n");
533 subscribe_battery_level(attr);
534
535 memcpy(&uuid, BT_UUID_BAS_BATTERY_LEVEL_STATUS, sizeof(uuid));
536 discover_params.uuid = &uuid.uuid;
537 discover_params.start_handle = attr->handle + 1;
538 discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
539
540 err = bt_gatt_discover(conn, &discover_params);
541 if (err) {
542 TEST_FAIL("Discover failed (err %d)\n", err);
543 }
544 } else if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_BAS_BATTERY_LEVEL_STATUS)) {
545 LOG_DBG("Subscribe Batterry Level Status Char\n");
546 subscribe_battery_level_status(attr);
547
548 memcpy(&uuid, BT_UUID_BAS_BATTERY_CRIT_STATUS, sizeof(uuid));
549 discover_params.uuid = &uuid.uuid;
550 discover_params.start_handle = attr->handle + 1;
551 discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
552
553 err = bt_gatt_discover(conn, &discover_params);
554 if (err) {
555 TEST_FAIL("Discover failed (err %d)\n", err);
556 }
557 } else if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_BAS_BATTERY_CRIT_STATUS)) {
558 LOG_DBG("Subscribe Batterry Critical Status Char\n");
559 subscribe_battery_critical_status(attr);
560 }
561 return BT_GATT_ITER_STOP;
562 }
563
discover_bas_service(struct bt_conn * conn)564 static void discover_bas_service(struct bt_conn *conn)
565 {
566 int err;
567
568 LOG_DBG("%s\n", __func__);
569
570 memcpy(&uuid, BT_UUID_BAS, sizeof(uuid));
571 discover_params.uuid = &uuid.uuid;
572 discover_params.func = discover_func;
573 discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
574 discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
575 discover_params.type = BT_GATT_DISCOVER_PRIMARY;
576 err = bt_gatt_discover(conn, &discover_params);
577 if (err) {
578 TEST_FAIL("Discover failed(err %d)\n", err);
579 return;
580 }
581 }
582
test_bas_central_main(void)583 static void test_bas_central_main(void)
584 {
585 int err;
586
587 /* Mark test as in progress. */
588 TEST_START("central");
589 /* bk_sync_init only works between two devices in a simulation, with IDs 0 and 1. */
590 if (get_device_nbr() == 1) {
591 /* Initialize device sync library */
592 bk_sync_init();
593 }
594
595 err = bt_enable(NULL);
596 TEST_ASSERT(err == 0, "Can't enable Bluetooth (err %d)", err);
597
598 LOG_DBG("Bluetooth initialized\n");
599
600 err = bt_testlib_scan_find_name(&peer, CONFIG_BT_DEVICE_NAME);
601 TEST_ASSERT(!err, "Failed to start scan (err %d)", err);
602
603 /* Create a connection using that address */
604 err = bt_testlib_connect(&peer, &default_conn);
605 TEST_ASSERT(!err, "Failed to initiate connection (err %d)", err);
606
607 LOG_DBG("Connected");
608 discover_bas_service(default_conn);
609
610 if (get_device_nbr() == 1) {
611 WAIT_FOR_FLAG(indication_count_reached);
612 LOG_INF("Indication Count Reached!");
613 } else {
614 WAIT_FOR_FLAG(notification_count_reached);
615 LOG_INF("Notification Count Reached!");
616 }
617 /* bk_sync_send only works between two devices in a simulation, with IDs 0 and 1. */
618 if (get_device_nbr() == 1) {
619 bk_sync_send();
620 }
621
622 printk("Read BCS once peripheral sets BLS Addl Status Service Required Flag to false\n");
623
624 UNSET_FLAG(bcs_char_read);
625
626 err = bt_gatt_read(default_conn, &read_bcs_params);
627 if (err != 0) {
628 TEST_FAIL("Battery Critical Status Read failed (err %d)\n", err);
629 }
630
631 WAIT_FOR_FLAG(bcs_char_read);
632
633 if (get_device_nbr() == 1) {
634 bk_sync_send();
635 }
636
637 bst_result = Passed;
638 TEST_PASS("Central Test Passed");
639 }
640
641 static const struct bst_test_instance test_bas_central[] = {
642 {
643 .test_id = "central",
644 .test_descr =
645 "Battery Service test. It expects that a peripheral device can be found. "
646 "The test will pass if it can receive notifications and indications more "
647 "than the threshold set within 15 sec. ",
648 .test_pre_init_f = test_bas_central_init,
649 .test_tick_f = test_bas_central_tick,
650 .test_main_f = test_bas_central_main,
651 },
652 BSTEST_END_MARKER,
653 };
654
test_bas_central_install(struct bst_test_list * tests)655 struct bst_test_list *test_bas_central_install(struct bst_test_list *tests)
656 {
657 tests = bst_add_tests(tests, test_bas_central);
658 return tests;
659 }
660