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