1 /* main_l2cap_ecred.c - Application main entry point */
2 
3 /*
4  * Copyright (c) 2022 Nordic Semiconductor
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <stddef.h>
10 
11 #include <zephyr/types.h>
12 #include <zephyr/sys/util.h>
13 #include <zephyr/sys/byteorder.h>
14 
15 #include <zephyr/bluetooth/bluetooth.h>
16 #include <zephyr/bluetooth/hci.h>
17 #include <zephyr/bluetooth/l2cap.h>
18 
19 #include "babblekit/testcase.h"
20 #include "babblekit/flags.h"
21 #include "babblekit/sync.h"
22 
23 #define LOG_MODULE_NAME main_l2cap_ecred
24 #include <zephyr/logging/log.h>
25 LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_DBG);
26 
27 extern enum bst_result_t bst_result;
28 
29 static struct bt_conn *default_conn;
30 
31 static const struct bt_data ad[] = {
32 	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
33 };
34 
35 #define DATA_MTU CONFIG_BT_L2CAP_TX_MTU
36 #define DATA_MPS 65
37 #define DATA_BUF_SIZE BT_L2CAP_SDU_BUF_SIZE(DATA_MTU)
38 #define L2CAP_CHANNELS 2
39 #define SERVERS 1
40 #define SDU_SEND_COUNT 200
41 #define ECRED_CHAN_MAX 5
42 #define LONG_MSG (DATA_MTU - 500)
43 #define SHORT_MSG (DATA_MPS - 2)
44 #define LONG_MSG_CHAN_IDX 0
45 #define SHORT_MSG_CHAN_IDX 1
46 
47 NET_BUF_POOL_FIXED_DEFINE(rx_data_pool, L2CAP_CHANNELS, BT_L2CAP_BUF_SIZE(DATA_BUF_SIZE), 8, NULL);
48 NET_BUF_POOL_FIXED_DEFINE(tx_data_pool_0, 1, BT_L2CAP_SDU_BUF_SIZE(DATA_MTU),
49 			  CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
50 NET_BUF_POOL_FIXED_DEFINE(tx_data_pool_1, 1, BT_L2CAP_SDU_BUF_SIZE(DATA_MTU),
51 			  CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
52 
53 static struct bt_l2cap_server servers[SERVERS];
54 void send_sdu_chan_worker(struct k_work *item);
55 struct channel {
56 	uint8_t chan_id; /* Internal number that identifies L2CAP channel. */
57 	struct bt_l2cap_le_chan le;
58 	bool in_use;
59 	size_t sdus_received;
60 	size_t bytes_to_send;
61 	uint8_t iteration;
62 	struct net_buf *buf;
63 	struct k_work work;
64 	struct k_work_q work_queue;
65 	uint8_t payload[DATA_MTU];
66 };
67 static struct channel channels[L2CAP_CHANNELS];
68 
69 DEFINE_FLAG_STATIC(is_connected);
70 DEFINE_FLAG_STATIC(unsequenced_data);
71 
72 #define T_STACK_SIZE 512
73 #define T_PRIORITY 5
74 
75 static K_THREAD_STACK_ARRAY_DEFINE(stack_area, L2CAP_CHANNELS, T_STACK_SIZE);
76 static K_SEM_DEFINE(chan_conn_sem, 0, L2CAP_CHANNELS);
77 static K_SEM_DEFINE(all_chan_conn_sem, 0, 1);
78 static K_SEM_DEFINE(all_chan_disconn_sem, 0, 1);
79 static K_SEM_DEFINE(sent_sem, 0, L2CAP_CHANNELS);
80 
init_workqs(void)81 static void init_workqs(void)
82 {
83 	for (int i = 0; i < L2CAP_CHANNELS; i++) {
84 		k_work_queue_init(&channels[i].work_queue);
85 		k_work_queue_start(&channels[i].work_queue, stack_area[i],
86 		K_THREAD_STACK_SIZEOF(*stack_area), T_PRIORITY, NULL);
87 	}
88 }
89 
chan_alloc_buf_cb(struct bt_l2cap_chan * chan)90 static struct net_buf *chan_alloc_buf_cb(struct bt_l2cap_chan *chan)
91 {
92 	LOG_DBG("Allocated on chan %p", chan);
93 	return net_buf_alloc(&rx_data_pool, K_FOREVER);
94 }
95 
chan_recv_cb(struct bt_l2cap_chan * l2cap_chan,struct net_buf * buf)96 static int chan_recv_cb(struct bt_l2cap_chan *l2cap_chan, struct net_buf *buf)
97 {
98 	struct bt_l2cap_le_chan *l2cap_le_chan = CONTAINER_OF(
99 			l2cap_chan, struct bt_l2cap_le_chan, chan);
100 	struct channel *chan = CONTAINER_OF(l2cap_le_chan, struct channel, le);
101 	const uint32_t received_iterration = net_buf_pull_le32(buf);
102 
103 	LOG_DBG("received_iterration %i sdus_received %i, chan_id: %d, data_length: %d",
104 		received_iterration, chan->sdus_received, chan->chan_id, buf->len);
105 	if (!IS_FLAG_SET(unsequenced_data) && received_iterration != chan->sdus_received) {
106 		TEST_FAIL("Received out of sequence data.");
107 	}
108 
109 	const int retval = memcmp(buf->data + sizeof(received_iterration),
110 			    chan->payload + sizeof(received_iterration),
111 			    buf->len - sizeof(received_iterration));
112 	if (retval) {
113 		TEST_FAIL("Payload received didn't match expected value memcmp returned %i",
114 			  retval);
115 	}
116 
117 	/*By the time we rx on long msg channel we should have already rx on short msg channel*/
118 	if (chan->chan_id == 0) {
119 		if (channels[SHORT_MSG_CHAN_IDX].sdus_received !=
120 			(channels[LONG_MSG_CHAN_IDX].sdus_received + 1)) {
121 			TEST_FAIL("Didn't receive on short msg channel first");
122 		}
123 	}
124 
125 	chan->sdus_received++;
126 
127 	return 0;
128 }
129 
chan_sent_cb(struct bt_l2cap_chan * l2cap_chan)130 static void chan_sent_cb(struct bt_l2cap_chan *l2cap_chan)
131 {
132 	struct bt_l2cap_le_chan *l2cap_le_chan = CONTAINER_OF(
133 			l2cap_chan, struct bt_l2cap_le_chan, chan);
134 	struct channel *chan = CONTAINER_OF(l2cap_le_chan, struct channel, le);
135 
136 	chan->buf = 0;
137 	k_sem_give(&sent_sem);
138 
139 	LOG_DBG("chan_id: %d", chan->chan_id);
140 }
141 
chan_connected_cb(struct bt_l2cap_chan * l2cap_chan)142 static void chan_connected_cb(struct bt_l2cap_chan *l2cap_chan)
143 {
144 	struct bt_l2cap_le_chan *l2cap_le_chan = CONTAINER_OF(
145 			l2cap_chan, struct bt_l2cap_le_chan, chan);
146 	struct channel *chan = CONTAINER_OF(l2cap_le_chan, struct channel, le);
147 
148 	LOG_DBG("chan_id: %d", chan->chan_id);
149 
150 	LOG_DBG("tx.mtu %d, tx.mps: %d, rx.mtu: %d, rx.mps %d", sys_cpu_to_le16(chan->le.tx.mtu),
151 		sys_cpu_to_le16(chan->le.tx.mps), sys_cpu_to_le16(chan->le.rx.mtu),
152 		sys_cpu_to_le16(chan->le.rx.mps));
153 
154 	k_sem_give(&chan_conn_sem);
155 
156 	if (k_sem_count_get(&chan_conn_sem) == L2CAP_CHANNELS) {
157 		k_sem_give(&all_chan_conn_sem);
158 		k_sem_reset(&all_chan_disconn_sem);
159 	}
160 }
161 
chan_disconnected_cb(struct bt_l2cap_chan * l2cap_chan)162 static void chan_disconnected_cb(struct bt_l2cap_chan *l2cap_chan)
163 {
164 	struct bt_l2cap_le_chan *l2cap_le_chan = CONTAINER_OF(
165 			l2cap_chan, struct bt_l2cap_le_chan, chan);
166 	struct channel *chan = CONTAINER_OF(l2cap_le_chan, struct channel, le);
167 
168 	LOG_DBG("chan_id: %d", chan->chan_id);
169 
170 	chan->in_use = false;
171 	k_sem_take(&chan_conn_sem, K_FOREVER);
172 
173 	if (k_sem_count_get(&chan_conn_sem) == 0) {
174 		k_sem_give(&all_chan_disconn_sem);
175 		k_sem_reset(&all_chan_conn_sem);
176 	}
177 }
178 
chan_status_cb(struct bt_l2cap_chan * l2cap_chan,atomic_t * status)179 static void chan_status_cb(struct bt_l2cap_chan *l2cap_chan, atomic_t *status)
180 {
181 	struct bt_l2cap_le_chan *l2cap_le_chan = CONTAINER_OF(
182 			l2cap_chan, struct bt_l2cap_le_chan, chan);
183 	struct channel *chan = CONTAINER_OF(l2cap_le_chan, struct channel, le);
184 
185 	LOG_DBG("chan_id: %d, status: %ld", chan->chan_id, *status);
186 }
187 
chan_released_cb(struct bt_l2cap_chan * l2cap_chan)188 static void chan_released_cb(struct bt_l2cap_chan *l2cap_chan)
189 {
190 	struct bt_l2cap_le_chan *l2cap_le_chan = CONTAINER_OF(
191 			l2cap_chan, struct bt_l2cap_le_chan, chan);
192 	struct channel *chan = CONTAINER_OF(l2cap_le_chan, struct channel, le);
193 
194 	LOG_DBG("chan_id: %d", chan->chan_id);
195 }
196 
chan_reconfigured_cb(struct bt_l2cap_chan * l2cap_chan)197 static void chan_reconfigured_cb(struct bt_l2cap_chan *l2cap_chan)
198 {
199 	struct bt_l2cap_le_chan *l2cap_le_chan = CONTAINER_OF(
200 			l2cap_chan, struct bt_l2cap_le_chan, chan);
201 	struct channel *chan = CONTAINER_OF(l2cap_le_chan, struct channel, le);
202 
203 	LOG_DBG("chan_id: %d", chan->chan_id);
204 }
205 
206 static const struct bt_l2cap_chan_ops l2cap_ops = {
207 	.alloc_buf = chan_alloc_buf_cb,
208 	.recv = chan_recv_cb,
209 	.sent = chan_sent_cb,
210 	.connected = chan_connected_cb,
211 	.disconnected = chan_disconnected_cb,
212 	.status = chan_status_cb,
213 	.released = chan_released_cb,
214 	.reconfigured = chan_reconfigured_cb,
215 };
216 
get_free_channel(void)217 static struct channel *get_free_channel(void)
218 {
219 	for (int idx = 0; idx < L2CAP_CHANNELS; idx++) {
220 		struct channel *chan = &channels[idx];
221 
222 		if (chan->in_use) {
223 			continue;
224 		}
225 
226 		chan->chan_id = idx;
227 		channels[idx].in_use = true;
228 		(void)memset(chan->payload, idx, sizeof(chan->payload));
229 		k_work_init(&chan->work, send_sdu_chan_worker);
230 		chan->le.chan.ops = &l2cap_ops;
231 		chan->le.rx.mtu = DATA_MTU;
232 		chan->le.rx.mps = DATA_MPS;
233 
234 		return chan;
235 	}
236 
237 	return NULL;
238 }
239 
connect_num_channels(uint8_t num_l2cap_channels)240 static void connect_num_channels(uint8_t num_l2cap_channels)
241 {
242 	struct bt_l2cap_chan *allocated_channels[ECRED_CHAN_MAX] = { NULL };
243 
244 	for (int i = 0; i < num_l2cap_channels; i++) {
245 		struct channel *chan = get_free_channel();
246 
247 		if (!chan) {
248 			TEST_FAIL("failed, chan not free");
249 			return;
250 		}
251 
252 		allocated_channels[i] = &chan->le.chan;
253 	}
254 
255 	const int err = bt_l2cap_ecred_chan_connect(default_conn, allocated_channels,
256 						     servers[0].psm);
257 
258 	if (err) {
259 		TEST_FAIL("can't connect ecred %d ", err);
260 	}
261 }
262 
disconnect_all_channels(void)263 static void disconnect_all_channels(void)
264 {
265 	for (int i = 0; i < ARRAY_SIZE(channels); i++) {
266 		if (channels[i].in_use) {
267 			LOG_DBG("Disconnecting channel: %d)", channels[i].chan_id);
268 			const int err = bt_l2cap_chan_disconnect(&channels[i].le.chan);
269 
270 			if (err) {
271 				LOG_DBG("can't disconnect channel (err: %d)", err);
272 			}
273 
274 			channels[i].in_use = false;
275 		}
276 	}
277 }
278 
accept(struct bt_conn * conn,struct bt_l2cap_server * server,struct bt_l2cap_chan ** l2cap_chan)279 static int accept(struct bt_conn *conn, struct bt_l2cap_server *server,
280 		  struct bt_l2cap_chan **l2cap_chan)
281 {
282 	struct channel *chan;
283 
284 	chan = get_free_channel();
285 	if (!chan) {
286 		return -ENOMEM;
287 	}
288 
289 	*l2cap_chan = &chan->le.chan;
290 
291 	return 0;
292 }
293 
get_free_server(void)294 static struct bt_l2cap_server *get_free_server(void)
295 {
296 	for (int i = 0; i < SERVERS; i++) {
297 		if (servers[i].psm) {
298 			continue;
299 		}
300 
301 		return &servers[i];
302 	}
303 
304 	return NULL;
305 }
306 
register_l2cap_server(void)307 static void register_l2cap_server(void)
308 {
309 	struct bt_l2cap_server *server;
310 
311 	server = get_free_server();
312 	if (!server) {
313 		TEST_FAIL("Failed to get free server");
314 		return;
315 	}
316 
317 	server->accept = accept;
318 	server->psm = 0;
319 
320 	if (bt_l2cap_server_register(server) < 0) {
321 		TEST_FAIL("Failed to get free server");
322 		return;
323 	}
324 
325 	LOG_DBG("L2CAP server registered, PSM:0x%X", server->psm);
326 }
327 
connected(struct bt_conn * conn,uint8_t conn_err)328 static void connected(struct bt_conn *conn, uint8_t conn_err)
329 {
330 	char addr[BT_ADDR_LE_STR_LEN];
331 
332 	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
333 
334 	if (conn_err) {
335 		TEST_FAIL("Failed to connect to %s (%u)", addr, conn_err);
336 		bt_conn_unref(default_conn);
337 		default_conn = NULL;
338 		return;
339 	}
340 
341 	default_conn = bt_conn_ref(conn);
342 	LOG_DBG("%s", addr);
343 
344 	SET_FLAG(is_connected);
345 }
346 
disconnected(struct bt_conn * conn,uint8_t reason)347 static void disconnected(struct bt_conn *conn, uint8_t reason)
348 {
349 	char addr[BT_ADDR_LE_STR_LEN];
350 
351 	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
352 
353 	LOG_DBG("%s (reason 0x%02x)", addr, reason);
354 
355 	if (default_conn != conn) {
356 		TEST_FAIL("Conn mismatch disconnect %s %s)", default_conn, conn);
357 		return;
358 	}
359 
360 	bt_conn_unref(default_conn);
361 	default_conn = NULL;
362 	UNSET_FLAG(is_connected);
363 }
364 
365 BT_CONN_CB_DEFINE(conn_callbacks) = {
366 	.connected = connected,
367 	.disconnected = disconnected,
368 };
369 
send_sdu(int iteration,int chan_idx,int bytes)370 static void send_sdu(int iteration, int chan_idx, int bytes)
371 {
372 	struct bt_l2cap_chan *chan = &channels[chan_idx].le.chan;
373 	struct net_buf *buf;
374 
375 	/* First 4 bytes in sent payload is iteration count */
376 	sys_put_le32(iteration, channels[chan_idx].payload);
377 
378 	if (channels[chan_idx].buf != 0) {
379 		TEST_FAIL("Buf should have been deallocated by now");
380 		return;
381 	}
382 
383 	if (chan_idx == 0) {
384 		buf = net_buf_alloc(&tx_data_pool_0, K_NO_WAIT);
385 	} else {
386 		buf = net_buf_alloc(&tx_data_pool_1, K_NO_WAIT);
387 	}
388 
389 	if (buf == NULL) {
390 		TEST_FAIL("Failed to get buff on ch %i, iteration %i should never happen", chan_idx,
391 		     chan_idx);
392 	}
393 
394 	channels[chan_idx].buf = buf;
395 	net_buf_reserve(buf, BT_L2CAP_SDU_CHAN_SEND_RESERVE);
396 	net_buf_add_mem(buf, channels[chan_idx].payload, bytes);
397 
398 	LOG_DBG("bt_l2cap_chan_sending ch: %i bytes: %i iteration: %i", chan_idx, bytes, iteration);
399 	const int ret = bt_l2cap_chan_send(chan, buf);
400 
401 	LOG_DBG("bt_l2cap_chan_send returned: %i", ret);
402 
403 	if (ret < 0) {
404 		TEST_FAIL("Error: send failed error: %i", ret);
405 		channels[chan_idx].buf = 0;
406 		net_buf_unref(buf);
407 	}
408 }
409 
send_sdu_chan_worker(struct k_work * item)410 void send_sdu_chan_worker(struct k_work *item)
411 {
412 	const struct channel *ch = CONTAINER_OF(item, struct channel, work);
413 
414 	send_sdu(ch->iteration, ch->chan_id, ch->bytes_to_send);
415 }
416 
send_sdu_concurrently(void)417 static void send_sdu_concurrently(void)
418 {
419 	for (int i = 0; i < SDU_SEND_COUNT; i++) {
420 		for (int k = 0; k < L2CAP_CHANNELS; k++) {
421 			channels[k].iteration = i;
422 			/* Assign the right msg to the right channel */
423 			channels[k].bytes_to_send = (k == LONG_MSG_CHAN_IDX) ? LONG_MSG : SHORT_MSG;
424 			const int err = k_work_submit_to_queue(&channels[k].work_queue,
425 								&channels[k].work);
426 
427 			if (err < 0) {
428 				TEST_FAIL("Failed to submit work to the queue, error: %d", err);
429 			}
430 		}
431 
432 		/* Wait until messages on all of the channels has been sent */
433 		for (int l = 0; l < L2CAP_CHANNELS; l++) {
434 			k_sem_take(&sent_sem, K_FOREVER);
435 		}
436 	}
437 }
438 
change_mtu_on_channels(int num_channels,int new_mtu)439 static int change_mtu_on_channels(int num_channels, int new_mtu)
440 {
441 	struct bt_l2cap_chan *reconf_channels[ECRED_CHAN_MAX] = { NULL };
442 
443 	for (int i = 0; i < num_channels; i++) {
444 		reconf_channels[i] = &(&channels[i])->le.chan;
445 	}
446 
447 	return bt_l2cap_ecred_chan_reconfigure(reconf_channels, new_mtu);
448 }
449 
test_peripheral_main(void)450 static void test_peripheral_main(void)
451 {
452 	TEST_ASSERT(bk_sync_init() == 0, "Failed to open backchannel");
453 	LOG_DBG("*L2CAP ECRED Peripheral started*");
454 	init_workqs();
455 	int err;
456 
457 	err = bt_enable(NULL);
458 	if (err) {
459 		TEST_FAIL("Can't enable Bluetooth (err %d)", err);
460 		return;
461 	}
462 
463 	LOG_DBG("Peripheral Bluetooth initialized.");
464 	LOG_DBG("Connectable advertising...");
465 	err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), NULL, 0);
466 	if (err) {
467 		TEST_FAIL("Advertising failed to start (err %d)", err);
468 		return;
469 	}
470 
471 	LOG_DBG("Advertising started.");
472 	LOG_DBG("Peripheral waiting for connection...");
473 	WAIT_FOR_FLAG(is_connected);
474 	LOG_DBG("Peripheral Connected.");
475 	register_l2cap_server();
476 	connect_num_channels(L2CAP_CHANNELS);
477 	k_sem_take(&all_chan_conn_sem, K_FOREVER);
478 
479 	/* Disconnect and reconnect channels *****************************************************/
480 	LOG_DBG("############# Disconnect and reconnect channels");
481 	disconnect_all_channels();
482 	k_sem_take(&all_chan_disconn_sem, K_FOREVER);
483 
484 	connect_num_channels(L2CAP_CHANNELS);
485 	k_sem_take(&all_chan_conn_sem, K_FOREVER);
486 
487 	LOG_DBG("Send sync after reconnection");
488 	bk_sync_send();
489 
490 	/* Send bytes on both channels and expect ch 1 to receive all of them before ch 0 *********/
491 	LOG_DBG("############# Send bytes on both channels concurrently");
492 	send_sdu_concurrently();
493 
494 	/* Change mtu size on all connected channels *********************************************/
495 	LOG_DBG("############# Change MTU of the channels");
496 	err = change_mtu_on_channels(L2CAP_CHANNELS, CONFIG_BT_L2CAP_TX_MTU + 10);
497 
498 	if (err) {
499 		TEST_FAIL("MTU change failed (err %d)", err);
500 	}
501 
502 	/* Read from both devices (Central and Peripheral) at the same time **********************/
503 	LOG_DBG("############# Read from both devices (Central and Peripheral) at the same time");
504 	LOG_DBG("Wait for sync before sending the msg");
505 	bk_sync_wait();
506 	LOG_DBG("Received sync");
507 	send_sdu(0, 1, 10);
508 
509 	k_sem_take(&sent_sem, K_FOREVER);
510 	disconnect_all_channels();
511 	WAIT_FOR_FLAG_UNSET(is_connected);
512 	TEST_PASS("L2CAP ECRED Peripheral tests Passed");
513 	bs_trace_silent_exit(0);
514 }
515 
device_found(const bt_addr_le_t * addr,int8_t rssi,uint8_t type,struct net_buf_simple * ad)516 static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
517 			 struct net_buf_simple *ad)
518 {
519 	struct bt_le_conn_param *param;
520 	int err;
521 
522 	err = bt_le_scan_stop();
523 	if (err) {
524 		TEST_FAIL("Stop LE scan failed (err %d)", err);
525 		return;
526 	}
527 
528 	param = BT_LE_CONN_PARAM_DEFAULT;
529 	err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, param, &default_conn);
530 	if (err) {
531 		TEST_FAIL("Create conn failed (err %d)", err);
532 		return;
533 	}
534 }
535 
test_central_main(void)536 static void test_central_main(void)
537 {
538 	struct bt_le_scan_param scan_param = {
539 		.type = BT_LE_SCAN_TYPE_ACTIVE,
540 		.options = BT_LE_SCAN_OPT_NONE,
541 		.interval = BT_GAP_SCAN_FAST_INTERVAL,
542 		.window = BT_GAP_SCAN_FAST_WINDOW,
543 	};
544 
545 	TEST_ASSERT(bk_sync_init() == 0, "Failed to open backchannel");
546 
547 	LOG_DBG("*L2CAP ECRED Central started*");
548 	int err;
549 
550 	err = bt_enable(NULL);
551 	if (err) {
552 		TEST_FAIL("Can't enable Bluetooth (err %d)", err);
553 		return;
554 	}
555 	LOG_DBG("Central Bluetooth initialized.\n");
556 
557 	err = bt_le_scan_start(&scan_param, device_found);
558 	if (err) {
559 		TEST_FAIL("Scanning failed to start (err %d)", err);
560 		return;
561 	}
562 
563 	LOG_DBG("Scanning successfully started\n");
564 
565 	LOG_DBG("Central waiting for connection...\n");
566 	WAIT_FOR_FLAG(is_connected);
567 	LOG_DBG("Central Connected.\n");
568 	register_l2cap_server();
569 
570 	LOG_DBG("Wait for sync after reconnection");
571 	bk_sync_wait();
572 	LOG_DBG("Received sync");
573 
574 	/* Read from both devices (Central and Peripheral) at the same time **********************/
575 	LOG_DBG("############# Read from both devices (Central and Peripheral) at the same time");
576 	LOG_DBG("Send sync for SDU send");
577 	SET_FLAG(unsequenced_data);
578 	bk_sync_send();
579 	send_sdu(0, 1, 10);
580 
581 	/* Wait until all of the channels are disconnected */
582 	k_sem_take(&all_chan_disconn_sem, K_FOREVER);
583 
584 	LOG_DBG("Both l2cap channels disconnected, test over\n");
585 
586 	UNSET_FLAG(unsequenced_data);
587 	LOG_DBG("received PDUs on long msg channel %i and short msg channel %i",
588 		channels[LONG_MSG_CHAN_IDX].sdus_received,
589 		channels[SHORT_MSG_CHAN_IDX].sdus_received);
590 
591 	if (channels[LONG_MSG_CHAN_IDX].sdus_received < SDU_SEND_COUNT ||
592 	    channels[SHORT_MSG_CHAN_IDX].sdus_received < SDU_SEND_COUNT) {
593 		TEST_FAIL("received less than %i", SDU_SEND_COUNT);
594 	}
595 
596 	/* Disconnect */
597 	LOG_DBG("Central Disconnecting....");
598 	err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
599 	bt_conn_unref(default_conn);
600 	LOG_DBG("Central tried to disconnect");
601 
602 	if (err) {
603 		TEST_FAIL("Disconnection failed (err %d)", err);
604 		return;
605 	}
606 
607 	LOG_DBG("Central Disconnected.");
608 
609 	TEST_PASS("L2CAP ECRED Central tests Passed");
610 }
611 
612 static const struct bst_test_instance test_def[] = {
613 	{
614 		.test_id = "peripheral",
615 		.test_descr = "Peripheral L2CAP ECRED",
616 		.test_main_f = test_peripheral_main
617 	},
618 	{
619 		.test_id = "central",
620 		.test_descr = "Central L2CAP ECRED",
621 		.test_main_f = test_central_main
622 	},
623 	BSTEST_END_MARKER
624 };
625 
test_main_l2cap_ecred_install(struct bst_test_list * tests)626 struct bst_test_list *test_main_l2cap_ecred_install(struct bst_test_list *tests)
627 {
628 	return bst_add_tests(tests, test_def);
629 }
630