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