1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 #include <stddef.h>
21 #include <errno.h>
22 #include "testutil/testutil.h"
23 #include "nimble/hci_common.h"
24 #include "host/ble_hs_test.h"
25 #include "ble_hs_test_util.h"
26
27 #define BLE_L2CAP_TEST_PSM (90)
28 #define BLE_L2CAP_TEST_CID (99)
29 #define BLE_L2CAP_TEST_COC_MTU (256)
30 /* We use same pool for incoming and outgoing sdu */
31 #define BLE_L2CAP_TEST_COC_BUF_COUNT (6 * MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM))
32
33 static uint16_t ble_l2cap_test_update_conn_handle;
34 static int ble_l2cap_test_update_status;
35 static void *ble_l2cap_test_update_arg;
36
37 static void *test_sdu_coc_mem;
38 struct os_mbuf_pool sdu_os_mbuf_pool;
39 static struct os_mempool sdu_coc_mbuf_mempool;
40 static uint16_t current_cid = 0x0040;
41 /*****************************************************************************
42 * $util *
43 *****************************************************************************/
44
45 static void
ble_l2cap_test_util_init(void)46 ble_l2cap_test_util_init(void)
47 {
48 ble_hs_test_util_init();
49 ble_l2cap_test_update_conn_handle = BLE_HS_CONN_HANDLE_NONE;
50 ble_l2cap_test_update_status = -1;
51 ble_l2cap_test_update_arg = (void *)(uintptr_t)-1;
52 int rc;
53
54 if (test_sdu_coc_mem) {
55 free(test_sdu_coc_mem);
56 }
57
58 /* For testing we want to support all the available channels */
59 test_sdu_coc_mem = malloc(
60 OS_MEMPOOL_BYTES(BLE_L2CAP_TEST_COC_BUF_COUNT,BLE_L2CAP_TEST_COC_MTU));
61 assert(test_sdu_coc_mem != NULL);
62
63 rc = os_mempool_init(&sdu_coc_mbuf_mempool, BLE_L2CAP_TEST_COC_BUF_COUNT,
64 BLE_L2CAP_TEST_COC_MTU, test_sdu_coc_mem,
65 "test_coc_sdu_pool");
66 assert(rc == 0);
67
68 rc = os_mbuf_pool_init(&sdu_os_mbuf_pool, &sdu_coc_mbuf_mempool,
69 BLE_L2CAP_TEST_COC_MTU, BLE_L2CAP_TEST_COC_BUF_COUNT);
70 assert(rc == 0);
71
72 }
73
74 static void
ble_l2cap_test_util_rx_update_req(uint16_t conn_handle,uint8_t id,struct ble_l2cap_sig_update_params * params)75 ble_l2cap_test_util_rx_update_req(uint16_t conn_handle, uint8_t id,
76 struct ble_l2cap_sig_update_params *params)
77 {
78 struct ble_l2cap_sig_update_req *req;
79 struct hci_data_hdr hci_hdr;
80 struct os_mbuf *om;
81 int rc;
82
83 hci_hdr = BLE_HS_TEST_UTIL_L2CAP_HCI_HDR(
84 2, BLE_HCI_PB_FIRST_FLUSH,
85 BLE_L2CAP_HDR_SZ + BLE_L2CAP_SIG_HDR_SZ + BLE_L2CAP_SIG_UPDATE_REQ_SZ);
86
87 req = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_UPDATE_REQ, id,
88 BLE_L2CAP_SIG_UPDATE_REQ_SZ, &om);
89 TEST_ASSERT_FATAL(req != NULL);
90
91 req->itvl_min = htole16(params->itvl_min);
92 req->itvl_max = htole16(params->itvl_max);
93 req->slave_latency = htole16(params->slave_latency);
94 req->timeout_multiplier = htole16(params->timeout_multiplier);
95
96 ble_hs_test_util_hci_ack_set(
97 ble_hs_hci_util_opcode_join(BLE_HCI_OGF_LE,
98 BLE_HCI_OCF_LE_CONN_UPDATE), 0);
99 rc = ble_hs_test_util_l2cap_rx_first_frag(conn_handle, BLE_L2CAP_CID_SIG,
100 &hci_hdr, om);
101 TEST_ASSERT_FATAL(rc == 0);
102 }
103
104 static void
ble_l2cap_test_util_verify_tx_update_conn(struct ble_gap_upd_params * params)105 ble_l2cap_test_util_verify_tx_update_conn(
106 struct ble_gap_upd_params *params)
107 {
108 uint8_t param_len;
109 uint8_t *param;
110
111 param = ble_hs_test_util_hci_verify_tx(BLE_HCI_OGF_LE,
112 BLE_HCI_OCF_LE_CONN_UPDATE,
113 ¶m_len);
114 TEST_ASSERT(param_len == BLE_HCI_CONN_UPDATE_LEN);
115 TEST_ASSERT(get_le16(param + 0) == 2);
116 TEST_ASSERT(get_le16(param + 2) == params->itvl_min);
117 TEST_ASSERT(get_le16(param + 4) == params->itvl_max);
118 TEST_ASSERT(get_le16(param + 6) == params->latency);
119 TEST_ASSERT(get_le16(param + 8) == params->supervision_timeout);
120 TEST_ASSERT(get_le16(param + 10) == params->min_ce_len);
121 TEST_ASSERT(get_le16(param + 12) == params->max_ce_len);
122 }
123
124 static int
ble_l2cap_test_util_dummy_rx(struct ble_l2cap_chan * chan)125 ble_l2cap_test_util_dummy_rx(struct ble_l2cap_chan *chan)
126 {
127 return 0;
128 }
129
130 static void
ble_l2cap_test_util_create_conn(uint16_t conn_handle,uint8_t * addr,ble_gap_event_fn * cb,void * cb_arg)131 ble_l2cap_test_util_create_conn(uint16_t conn_handle, uint8_t *addr,
132 ble_gap_event_fn *cb, void *cb_arg)
133 {
134 struct ble_l2cap_chan *chan;
135 struct ble_hs_conn *conn;
136
137 ble_hs_test_util_create_conn(conn_handle, addr, cb, cb_arg);
138
139 ble_hs_lock();
140
141 conn = ble_hs_conn_find(conn_handle);
142 TEST_ASSERT_FATAL(conn != NULL);
143
144 chan = ble_l2cap_chan_alloc(conn_handle);
145 TEST_ASSERT_FATAL(chan != NULL);
146
147 chan->scid = BLE_L2CAP_TEST_CID;
148 chan->my_mtu = 240;
149 chan->rx_fn = ble_l2cap_test_util_dummy_rx;
150
151 ble_hs_conn_chan_insert(conn, chan);
152
153 ble_hs_test_util_hci_out_clear();
154
155 ble_hs_unlock();
156 }
157
158 static int
ble_l2cap_test_util_rx_first_frag(uint16_t conn_handle,uint16_t l2cap_frag_len,uint16_t cid,uint16_t l2cap_len)159 ble_l2cap_test_util_rx_first_frag(uint16_t conn_handle,
160 uint16_t l2cap_frag_len,
161 uint16_t cid, uint16_t l2cap_len)
162 {
163 struct hci_data_hdr hci_hdr;
164 struct os_mbuf *om;
165 uint16_t hci_len;
166 void *v;
167 int rc;
168
169 om = ble_hs_mbuf_l2cap_pkt();
170 TEST_ASSERT_FATAL(om != NULL);
171
172 v = os_mbuf_extend(om, l2cap_frag_len);
173 TEST_ASSERT_FATAL(v != NULL);
174
175 om = ble_l2cap_prepend_hdr(om, cid, l2cap_len);
176 TEST_ASSERT_FATAL(om != NULL);
177
178 hci_len = sizeof hci_hdr + l2cap_frag_len;
179 hci_hdr = BLE_HS_TEST_UTIL_L2CAP_HCI_HDR(conn_handle,
180 BLE_HCI_PB_FIRST_FLUSH, hci_len);
181 rc = ble_hs_test_util_l2cap_rx(conn_handle, &hci_hdr, om);
182 return rc;
183 }
184
185 static int
ble_l2cap_test_util_rx_next_frag(uint16_t conn_handle,uint16_t hci_len)186 ble_l2cap_test_util_rx_next_frag(uint16_t conn_handle, uint16_t hci_len)
187 {
188 struct hci_data_hdr hci_hdr;
189 struct os_mbuf *om;
190 void *v;
191 int rc;
192
193 om = ble_hs_mbuf_l2cap_pkt();
194 TEST_ASSERT_FATAL(om != NULL);
195
196 v = os_mbuf_extend(om, hci_len);
197 TEST_ASSERT_FATAL(v != NULL);
198
199 hci_hdr = BLE_HS_TEST_UTIL_L2CAP_HCI_HDR(conn_handle,
200 BLE_HCI_PB_MIDDLE, hci_len);
201 rc = ble_hs_test_util_l2cap_rx(conn_handle, &hci_hdr, om);
202 return rc;
203 }
204
205 static void
ble_l2cap_test_util_verify_first_frag(uint16_t conn_handle,uint16_t l2cap_frag_len,uint16_t l2cap_len)206 ble_l2cap_test_util_verify_first_frag(uint16_t conn_handle,
207 uint16_t l2cap_frag_len,
208 uint16_t l2cap_len)
209 {
210 struct ble_hs_conn *conn;
211 int rc;
212
213 rc = ble_l2cap_test_util_rx_first_frag(conn_handle, l2cap_frag_len,
214 BLE_L2CAP_TEST_CID, l2cap_len);
215 TEST_ASSERT(rc == 0);
216
217 ble_hs_lock();
218
219 conn = ble_hs_conn_find(conn_handle);
220 TEST_ASSERT_FATAL(conn != NULL);
221 TEST_ASSERT(conn->bhc_rx_chan != NULL &&
222 conn->bhc_rx_chan->scid == BLE_L2CAP_TEST_CID);
223
224 ble_hs_unlock();
225 }
226
227 static void
ble_l2cap_test_util_verify_middle_frag(uint16_t conn_handle,uint16_t hci_len)228 ble_l2cap_test_util_verify_middle_frag(uint16_t conn_handle,
229 uint16_t hci_len)
230 {
231 struct ble_hs_conn *conn;
232 int rc;
233
234 rc = ble_l2cap_test_util_rx_next_frag(conn_handle, hci_len);
235 TEST_ASSERT(rc == 0);
236
237 ble_hs_lock();
238
239 conn = ble_hs_conn_find(conn_handle);
240 TEST_ASSERT_FATAL(conn != NULL);
241 TEST_ASSERT(conn->bhc_rx_chan != NULL &&
242 conn->bhc_rx_chan->scid == BLE_L2CAP_TEST_CID);
243
244 ble_hs_unlock();
245 }
246
247 static void
ble_l2cap_test_util_verify_last_frag(uint16_t conn_handle,uint16_t hci_len)248 ble_l2cap_test_util_verify_last_frag(uint16_t conn_handle,
249 uint16_t hci_len)
250 {
251 struct ble_hs_conn *conn;
252 int rc;
253
254 rc = ble_l2cap_test_util_rx_next_frag(conn_handle, hci_len);
255 TEST_ASSERT(rc == 0);
256
257 ble_hs_lock();
258
259 conn = ble_hs_conn_find(conn_handle);
260 TEST_ASSERT_FATAL(conn != NULL);
261 TEST_ASSERT(conn->bhc_rx_chan == NULL);
262
263 ble_hs_unlock();
264 }
265
266 /*****************************************************************************
267 * $rx *
268 *****************************************************************************/
269
TEST_CASE(ble_l2cap_test_case_bad_header)270 TEST_CASE(ble_l2cap_test_case_bad_header)
271 {
272 int rc;
273
274 ble_l2cap_test_util_init();
275
276 ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
277 NULL, NULL);
278
279 rc = ble_l2cap_test_util_rx_first_frag(2, 14, 1234, 10);
280 TEST_ASSERT(rc == BLE_HS_ENOENT);
281 }
282
TEST_CASE(ble_l2cap_test_case_bad_handle)283 TEST_CASE(ble_l2cap_test_case_bad_handle)
284 {
285 int rc;
286
287 ble_l2cap_test_util_init();
288
289 ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
290 NULL, NULL);
291
292 rc = ble_l2cap_test_util_rx_first_frag(1234, 14, 1234, 10);
293 TEST_ASSERT(rc == BLE_HS_ENOTCONN);
294
295 /* Ensure we did not send anything in return. */
296 TEST_ASSERT_FATAL(ble_hs_test_util_prev_tx_dequeue() == NULL);
297 }
298
299 /*****************************************************************************
300 * $fragmentation *
301 *****************************************************************************/
302
TEST_CASE(ble_l2cap_test_case_frag_single)303 TEST_CASE(ble_l2cap_test_case_frag_single)
304 {
305 struct hci_data_hdr hci_hdr;
306 struct os_mbuf *om;
307 int rc;
308
309 ble_l2cap_test_util_init();
310
311 ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
312 NULL, NULL);
313
314 /*** HCI header specifies middle fragment without start. */
315 hci_hdr = BLE_HS_TEST_UTIL_L2CAP_HCI_HDR(2, BLE_HCI_PB_MIDDLE, 10);
316
317 om = ble_hs_mbuf_l2cap_pkt();
318 TEST_ASSERT_FATAL(om != NULL);
319
320 om = ble_l2cap_prepend_hdr(om, 0, 5);
321 TEST_ASSERT_FATAL(om != NULL);
322
323 rc = ble_hs_test_util_l2cap_rx(2, &hci_hdr, om);
324 TEST_ASSERT(rc == BLE_HS_EBADDATA);
325
326 /*** Packet consisting of three fragments. */
327 ble_l2cap_test_util_verify_first_frag(2, 10, 30);
328 ble_l2cap_test_util_verify_middle_frag(2, 10);
329 ble_l2cap_test_util_verify_last_frag(2, 10);
330
331 /*** Packet consisting of five fragments. */
332 ble_l2cap_test_util_verify_first_frag(2, 8, 49);
333 ble_l2cap_test_util_verify_middle_frag(2, 13);
334 ble_l2cap_test_util_verify_middle_frag(2, 2);
335 ble_l2cap_test_util_verify_middle_frag(2, 21);
336 ble_l2cap_test_util_verify_last_frag(2, 5);
337 }
338
TEST_CASE(ble_l2cap_test_case_frag_multiple)339 TEST_CASE(ble_l2cap_test_case_frag_multiple)
340 {
341 ble_l2cap_test_util_init();
342
343 ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
344 NULL, NULL);
345 ble_l2cap_test_util_create_conn(3, ((uint8_t[]){2,3,4,5,6,7}),
346 NULL, NULL);
347 ble_l2cap_test_util_create_conn(4, ((uint8_t[]){3,4,5,6,7,8}),
348 NULL, NULL);
349
350 ble_l2cap_test_util_verify_first_frag(2, 3, 10);
351 ble_l2cap_test_util_verify_first_frag(3, 2, 5);
352 ble_l2cap_test_util_verify_middle_frag(2, 6);
353 ble_l2cap_test_util_verify_first_frag(4, 1, 4);
354 ble_l2cap_test_util_verify_middle_frag(3, 2);
355 ble_l2cap_test_util_verify_last_frag(3, 1);
356 ble_l2cap_test_util_verify_middle_frag(4, 2);
357 ble_l2cap_test_util_verify_last_frag(4, 1);
358 ble_l2cap_test_util_verify_last_frag(2, 1);
359 }
360
TEST_CASE(ble_l2cap_test_case_frag_channels)361 TEST_CASE(ble_l2cap_test_case_frag_channels)
362 {
363 struct ble_hs_conn *conn;
364 int rc;
365 uint16_t data_len = 30;
366
367 ble_l2cap_test_util_init();
368
369 ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
370 NULL, NULL);
371
372 /* Receive a starting fragment on the first channel. */
373 rc = ble_l2cap_test_util_rx_first_frag(2, 14, BLE_L2CAP_TEST_CID, data_len);
374 TEST_ASSERT(rc == 0);
375
376 ble_hs_lock();
377 conn = ble_hs_conn_find(2);
378 TEST_ASSERT_FATAL(conn != NULL);
379 TEST_ASSERT(conn->bhc_rx_chan != NULL &&
380 conn->bhc_rx_chan->scid == BLE_L2CAP_TEST_CID);
381 ble_hs_unlock();
382
383 /* Receive a starting fragment on a different channel. The first fragment
384 * should get discarded.
385 */
386 ble_hs_test_util_set_att_mtu(conn->bhc_handle, data_len);
387 rc = ble_l2cap_test_util_rx_first_frag(2, 14, BLE_L2CAP_CID_ATT, data_len);
388 TEST_ASSERT(rc == 0);
389
390 ble_hs_lock();
391 conn = ble_hs_conn_find(2);
392 TEST_ASSERT_FATAL(conn != NULL);
393 TEST_ASSERT(conn->bhc_rx_chan != NULL &&
394 conn->bhc_rx_chan->scid == BLE_L2CAP_CID_ATT);
395 ble_hs_unlock();
396
397 /* Terminate the connection. The received fragments should get freed.
398 * Mbuf leaks are tested in the post-test-case callback.
399 */
400 ble_hs_test_util_conn_disconnect(2);
401 }
402
TEST_CASE(ble_l2cap_test_case_frag_timeout)403 TEST_CASE(ble_l2cap_test_case_frag_timeout)
404 {
405 int32_t ticks_from_now;
406 int rc;
407
408 ble_l2cap_test_util_init();
409
410 ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
411 NULL, NULL);
412
413 /* Ensure timer is not set. */
414 ticks_from_now = ble_hs_conn_timer();
415 TEST_ASSERT_FATAL(ticks_from_now == BLE_HS_FOREVER);
416
417 /* Receive the first fragment of a multipart ACL data packet. */
418 rc = ble_l2cap_test_util_rx_first_frag(2, 14, BLE_L2CAP_TEST_CID, 30);
419 TEST_ASSERT_FATAL(rc == 0);
420
421 /* Ensure timer will expire in 30 seconds. */
422 ticks_from_now = ble_hs_conn_timer();
423 TEST_ASSERT(ticks_from_now == MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT));
424
425 /* Almost let the timer expire. */
426 os_time_advance(MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT) - 1);
427 ticks_from_now = ble_hs_conn_timer();
428 TEST_ASSERT(ticks_from_now == 1);
429
430 /* Receive a second fragment. */
431 rc = ble_l2cap_test_util_rx_next_frag(2, 14);
432 TEST_ASSERT_FATAL(rc == 0);
433
434 /* Ensure timer got reset. */
435 ticks_from_now = ble_hs_conn_timer();
436 TEST_ASSERT(ticks_from_now == MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT));
437
438 /* Allow the timer to expire. */
439 ble_hs_test_util_hci_ack_set_disconnect(0);
440 os_time_advance(MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT));
441 ticks_from_now = ble_hs_conn_timer();
442 TEST_ASSERT(ticks_from_now == BLE_HS_FOREVER);
443
444 /* Ensure connection was terminated. */
445 ble_hs_test_util_hci_verify_tx_disconnect(2, BLE_ERR_REM_USER_CONN_TERM);
446 }
447
448 /*****************************************************************************
449 * $unsolicited response *
450 *****************************************************************************/
451
TEST_CASE(ble_l2cap_test_case_sig_unsol_rsp)452 TEST_CASE(ble_l2cap_test_case_sig_unsol_rsp)
453 {
454 int rc;
455
456 ble_l2cap_test_util_init();
457
458 ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
459 NULL, NULL);
460
461 /* Receive an unsolicited response. */
462 rc = ble_hs_test_util_rx_l2cap_update_rsp(2, 100, 0);
463 TEST_ASSERT(rc == 0);
464
465 /* Ensure we did not send anything in return. */
466 TEST_ASSERT_FATAL(ble_hs_test_util_prev_tx_dequeue() == NULL);
467 }
468
469 /*****************************************************************************
470 * $update *
471 *****************************************************************************/
472
473 static int
ble_l2cap_test_util_conn_cb(struct ble_gap_event * event,void * arg)474 ble_l2cap_test_util_conn_cb(struct ble_gap_event *event, void *arg)
475 {
476 int *accept;
477
478 switch (event->type) {
479 case BLE_GAP_EVENT_L2CAP_UPDATE_REQ:
480 accept = arg;
481 return !*accept;
482
483 default:
484 return 0;
485 }
486 }
487
488 static void
ble_l2cap_test_util_peer_updates(int accept)489 ble_l2cap_test_util_peer_updates(int accept)
490 {
491 struct ble_l2cap_sig_update_params l2cap_params;
492 struct ble_gap_upd_params params;
493
494 ble_l2cap_test_util_init();
495
496 ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
497 ble_l2cap_test_util_conn_cb,
498 &accept);
499
500 l2cap_params.itvl_min = 0x200;
501 l2cap_params.itvl_max = 0x300;
502 l2cap_params.slave_latency = 0;
503 l2cap_params.timeout_multiplier = 0x500;
504 ble_l2cap_test_util_rx_update_req(2, 1, &l2cap_params);
505
506 /* Ensure an update response command got sent. */
507 ble_hs_test_util_verify_tx_l2cap_update_rsp(1, !accept);
508
509 if (accept) {
510 params.itvl_min = 0x200;
511 params.itvl_max = 0x300;
512 params.latency = 0;
513 params.supervision_timeout = 0x500;
514 params.min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN;
515 params.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN;
516 ble_l2cap_test_util_verify_tx_update_conn(¶ms);
517 } else {
518 /* Ensure no update got scheduled. */
519 TEST_ASSERT(!ble_gap_dbg_update_active(2));
520 }
521 }
522
523 static void
ble_l2cap_test_util_update_cb(uint16_t conn_handle,int status,void * arg)524 ble_l2cap_test_util_update_cb(uint16_t conn_handle, int status, void *arg)
525 {
526 ble_l2cap_test_update_conn_handle = conn_handle;
527 ble_l2cap_test_update_status = status;
528 ble_l2cap_test_update_arg = arg;
529 }
530
531 static void
ble_l2cap_test_util_we_update(int peer_accepts)532 ble_l2cap_test_util_we_update(int peer_accepts)
533 {
534 struct ble_l2cap_sig_update_params params;
535 uint8_t id;
536 int rc;
537
538 ble_l2cap_test_util_init();
539
540 ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
541 ble_l2cap_test_util_conn_cb, NULL);
542
543 /* Only the slave can initiate the L2CAP connection update procedure. */
544 ble_hs_atomic_conn_set_flags(2, BLE_HS_CONN_F_MASTER, 0);
545
546 params.itvl_min = 0x200;
547 params.itvl_max = 0x300;
548 params.slave_latency = 0;
549 params.timeout_multiplier = 0x100;
550 rc = ble_l2cap_sig_update(2, ¶ms, ble_l2cap_test_util_update_cb, NULL);
551 TEST_ASSERT_FATAL(rc == 0);
552
553 /* Ensure an update request got sent. */
554 id = ble_hs_test_util_verify_tx_l2cap_update_req(¶ms);
555
556 /* Receive response from peer. */
557 rc = ble_hs_test_util_rx_l2cap_update_rsp(2, id, !peer_accepts);
558 TEST_ASSERT(rc == 0);
559
560 /* Ensure callback got called. */
561 if (peer_accepts) {
562 TEST_ASSERT(ble_l2cap_test_update_status == 0);
563 } else {
564 TEST_ASSERT(ble_l2cap_test_update_status == BLE_HS_EREJECT);
565 }
566 TEST_ASSERT(ble_l2cap_test_update_arg == NULL);
567 }
568
TEST_CASE(ble_l2cap_test_case_sig_update_accept)569 TEST_CASE(ble_l2cap_test_case_sig_update_accept)
570 {
571 ble_l2cap_test_util_peer_updates(1);
572 }
573
TEST_CASE(ble_l2cap_test_case_sig_update_reject)574 TEST_CASE(ble_l2cap_test_case_sig_update_reject)
575 {
576 ble_l2cap_test_util_peer_updates(0);
577 }
578
TEST_CASE(ble_l2cap_test_case_sig_update_init_accept)579 TEST_CASE(ble_l2cap_test_case_sig_update_init_accept)
580 {
581 ble_l2cap_test_util_we_update(1);
582 }
583
TEST_CASE(ble_l2cap_test_case_sig_update_init_reject)584 TEST_CASE(ble_l2cap_test_case_sig_update_init_reject)
585 {
586 ble_l2cap_test_util_we_update(0);
587 }
588
TEST_CASE(ble_l2cap_test_case_sig_update_init_fail_master)589 TEST_CASE(ble_l2cap_test_case_sig_update_init_fail_master)
590 {
591 struct ble_l2cap_sig_update_params params;
592 int rc;
593
594 ble_l2cap_test_util_init();
595
596 ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
597 ble_l2cap_test_util_conn_cb, NULL);
598
599 params.itvl_min = 0x200;
600 params.itvl_max = 0x300;
601 params.slave_latency = 0;
602 params.timeout_multiplier = 0x100;
603 rc = ble_l2cap_sig_update(2, ¶ms, ble_l2cap_test_util_update_cb, NULL);
604 TEST_ASSERT_FATAL(rc == BLE_HS_EINVAL);
605
606 /* Ensure callback never called. */
607 TEST_ASSERT(ble_l2cap_test_update_status == -1);
608 }
609
TEST_CASE(ble_l2cap_test_case_sig_update_init_fail_bad_id)610 TEST_CASE(ble_l2cap_test_case_sig_update_init_fail_bad_id)
611 {
612 struct ble_l2cap_sig_update_params params;
613 uint8_t id;
614 int rc;
615
616 ble_l2cap_test_util_init();
617
618 ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
619 ble_l2cap_test_util_conn_cb, NULL);
620
621 /* Only the slave can initiate the L2CAP connection update procedure. */
622 ble_hs_atomic_conn_set_flags(2, BLE_HS_CONN_F_MASTER, 0);
623
624 params.itvl_min = 0x200;
625 params.itvl_max = 0x300;
626 params.slave_latency = 0;
627 params.timeout_multiplier = 0x100;
628 rc = ble_l2cap_sig_update(2, ¶ms, ble_l2cap_test_util_update_cb, NULL);
629 TEST_ASSERT_FATAL(rc == 0);
630
631 /* Ensure an update request got sent. */
632 id = ble_hs_test_util_verify_tx_l2cap_update_req(¶ms);
633
634 /* Receive response from peer with incorrect ID. */
635 rc = ble_hs_test_util_rx_l2cap_update_rsp(2, id + 1, 0);
636 TEST_ASSERT(rc == 0);
637
638 /* Ensure callback did not get called. */
639 TEST_ASSERT(ble_l2cap_test_update_status == -1);
640
641 /* Receive response from peer with correct ID. */
642 rc = ble_hs_test_util_rx_l2cap_update_rsp(2, id, 0);
643 TEST_ASSERT(rc == 0);
644
645 /* Ensure callback got called. */
646 TEST_ASSERT(ble_l2cap_test_update_status == 0);
647 TEST_ASSERT(ble_l2cap_test_update_arg == NULL);
648 }
649
650 /* Test enum but first four events matches to events which L2CAP sends to
651 * application. We need this in order to add additional SEND_DATA event for
652 * testing
653 */
654
655 enum {
656 BLE_L2CAP_TEST_EVENT_COC_CONNECT = 0,
657 BLE_L2CAP_TEST_EVENT_COC_DISCONNECT,
658 BLE_L2CAP_TEST_EVENT_COC_ACCEPT,
659 BLE_L2CAP_TEST_EVENT_COC_RECV_DATA,
660 BLE_L2CAP_TEST_EVENT_COC_SEND_DATA,
661 };
662
663 struct event {
664 uint8_t type;
665 uint16_t early_error;
666 uint16_t l2cap_status;
667 uint16_t app_status;
668 uint8_t handled;
669 uint8_t *data;
670 uint16_t data_len;
671 };
672
673 struct test_data {
674 struct event event[3];
675 uint16_t expected_num_of_ev;
676 /* This we use to track number of events sent to application*/
677 uint16_t event_cnt;
678 /* This we use to track verified events (received or not) */
679 uint16_t event_iter;
680 uint16_t psm;
681 uint16_t mtu;
682 struct ble_l2cap_chan *chan;
683 };
684
685 static int
ble_l2cap_test_event(struct ble_l2cap_event * event,void * arg)686 ble_l2cap_test_event(struct ble_l2cap_event *event, void *arg)
687 {
688 struct test_data *t = arg;
689 struct event *ev = &t->event[t->event_cnt++];
690 struct os_mbuf *sdu_rx;
691
692 assert(ev->type == event->type);
693 ev->handled = 1;
694 switch(event->type) {
695 case BLE_L2CAP_EVENT_COC_CONNECTED:
696 assert(ev->app_status == event->connect.status);
697 t->chan = event->connect.chan;
698 return 0;
699 case BLE_L2CAP_EVENT_COC_DISCONNECTED:
700 return 0;
701 case BLE_L2CAP_EVENT_COC_ACCEPT:
702 if (ev->app_status != 0) {
703 return ev->app_status;
704 }
705
706 sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
707 assert(sdu_rx != NULL);
708 ble_l2cap_recv_ready(event->accept.chan, sdu_rx);
709
710 return 0;
711
712 case BLE_L2CAP_EVENT_COC_DATA_RECEIVED:
713 sdu_rx = os_mbuf_pullup(event->receive.sdu_rx,
714 OS_MBUF_PKTLEN(event->receive.sdu_rx));
715 TEST_ASSERT(memcmp(sdu_rx->om_data, ev->data, ev->data_len) == 0);
716 return 0;
717 default:
718 return 0;
719 }
720 }
721
722 static void
ble_l2cap_test_coc_connect(struct test_data * t)723 ble_l2cap_test_coc_connect(struct test_data *t)
724 {
725 struct ble_l2cap_sig_le_con_req req = {};
726 struct ble_l2cap_sig_le_con_rsp rsp = {};
727 struct os_mbuf *sdu_rx;
728 struct event *ev = &t->event[t->event_iter++];
729 uint8_t id;
730 int rc;
731
732 ble_l2cap_test_util_init();
733
734 ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
735 ble_l2cap_test_util_conn_cb, NULL);
736
737 sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
738 assert(sdu_rx != NULL);
739
740 rc = ble_l2cap_sig_coc_connect(2, t->psm, t->mtu, sdu_rx,
741 ble_l2cap_test_event, t);
742 TEST_ASSERT_FATAL(rc == ev->early_error);
743
744 if (rc != 0) {
745 rc = os_mbuf_free_chain(sdu_rx);
746 TEST_ASSERT_FATAL(rc == 0);
747 return;
748 }
749
750 req.credits = htole16((t->mtu + (BLE_L2CAP_COC_MTU - 1) / 2) /
751 BLE_L2CAP_COC_MTU);
752 req.mps = htole16(BLE_L2CAP_COC_MTU);
753 req.mtu = htole16(t->mtu);
754 req.psm = htole16(t->psm);
755 req.scid = htole16(current_cid++);
756
757 /* Ensure an update request got sent. */
758 id = ble_hs_test_util_verify_tx_l2cap_sig(
759 BLE_L2CAP_SIG_OP_CREDIT_CONNECT_REQ,
760 &req, sizeof(req));
761
762 /* Use some different parameters for peer. Just keep mtu same for testing
763 * only*/
764 rsp.credits = htole16(10);
765 rsp.dcid = htole16(current_cid);
766 rsp.mps = htole16(BLE_L2CAP_COC_MTU + 16);
767 rsp.mtu = htole16(t->mtu);
768 rsp.result = htole16(ev->l2cap_status);
769
770 rc = ble_hs_test_util_inject_rx_l2cap_sig(2,
771 BLE_L2CAP_SIG_OP_CREDIT_CONNECT_RSP,
772 id, &rsp, sizeof(rsp));
773 TEST_ASSERT(rc == 0);
774
775 /* Ensure callback got called. */
776 TEST_ASSERT(ev->handled);
777 }
778
779 static void
ble_l2cap_test_coc_connect_by_peer(struct test_data * t)780 ble_l2cap_test_coc_connect_by_peer(struct test_data *t)
781 {
782 struct ble_l2cap_sig_le_con_req req = {};
783 struct ble_l2cap_sig_le_con_rsp rsp = {};
784 uint8_t id = 10;
785 int rc;
786 struct event *ev = &t->event[t->event_iter++];
787
788 ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
789 ble_l2cap_test_util_conn_cb, NULL);
790
791 /* Use some different parameters for peer */
792 req.credits = htole16(30);
793 req.mps = htole16(BLE_L2CAP_COC_MTU + 16);
794 req.mtu = htole16(t->mtu);
795 req.psm = htole16(t->psm);
796 req.scid = htole16(0x0040);
797
798 /* Receive remote request*/
799 rc = ble_hs_test_util_inject_rx_l2cap_sig(2,
800 BLE_L2CAP_SIG_OP_CREDIT_CONNECT_REQ,
801 id, &req, sizeof(req));
802 TEST_ASSERT_FATAL(rc == 0);
803
804 if (ev->type == BLE_L2CAP_EVENT_COC_ACCEPT) {
805 /* Lets check if there is accept event */
806 TEST_ASSERT(ev->handled);
807 /* Ensure callback got called. */
808 ev = &t->event[t->event_iter++];
809 }
810
811 if (ev->l2cap_status != 0) {
812 rsp.result = htole16(ev->l2cap_status);
813 } else {
814 /* Receive response from peer.*/
815 rsp.credits = htole16((t->mtu + (BLE_L2CAP_COC_MTU - 1) / 2) /
816 BLE_L2CAP_COC_MTU);
817 rsp.dcid = current_cid++;
818 rsp.mps = htole16(BLE_L2CAP_COC_MTU);
819 rsp.mtu = htole16(t->mtu);
820 }
821
822 /* Ensure we sent response. */
823 TEST_ASSERT(id == ble_hs_test_util_verify_tx_l2cap_sig(
824 BLE_L2CAP_SIG_OP_CREDIT_CONNECT_RSP,
825 &rsp, sizeof(rsp)));
826
827 if (ev->l2cap_status == 0) {
828 TEST_ASSERT(ev->handled);
829 } else {
830 TEST_ASSERT(!ev->handled);
831 }
832 }
833
834 static void
ble_l2cap_test_coc_disc(struct test_data * t)835 ble_l2cap_test_coc_disc(struct test_data *t)
836 {
837 struct ble_l2cap_sig_disc_req req;
838 struct event *ev = &t->event[t->event_iter++];
839 uint8_t id;
840 int rc;
841
842 rc = ble_l2cap_sig_disconnect(t->chan);
843 TEST_ASSERT_FATAL(rc == 0);
844
845 req.dcid = htole16(t->chan->dcid);
846 req.scid = htole16(t->chan->scid);
847
848 /* Ensure an update request got sent. */
849 id = ble_hs_test_util_verify_tx_l2cap_sig(BLE_L2CAP_SIG_OP_DISCONN_REQ,
850 &req, sizeof(req));
851
852 /* Receive response from peer. Note it shall be same as request */
853 rc = ble_hs_test_util_inject_rx_l2cap_sig(2, BLE_L2CAP_SIG_OP_DISCONN_RSP,
854 id, &req, sizeof(req));
855 TEST_ASSERT(rc == 0);
856
857 /* Ensure callback got called. */
858 TEST_ASSERT(ev->handled);
859 }
860
861 static void
ble_l2cap_test_coc_disc_by_peer(struct test_data * t)862 ble_l2cap_test_coc_disc_by_peer(struct test_data *t)
863 {
864 struct ble_l2cap_sig_disc_req req;
865 struct event *ev = &t->event[t->event_iter++];
866 uint8_t id = 10;
867 int rc;
868
869 /* Receive disconnect request from peer. Note that source cid
870 * and destination cid are from peer perspective */
871 req.dcid = htole16(t->chan->scid);
872 req.scid = htole16(t->chan->dcid);
873
874 rc = ble_hs_test_util_inject_rx_l2cap_sig(2, BLE_L2CAP_SIG_OP_DISCONN_REQ,
875 id, &req, sizeof(req));
876 TEST_ASSERT(rc == 0);
877
878 /* Ensure callback got called. */
879 TEST_ASSERT(ev->handled);
880
881 /* Ensure an we sent back response. Note that payload is same as request,
882 * lets reuse it */
883 TEST_ASSERT(ble_hs_test_util_verify_tx_l2cap_sig(
884 BLE_L2CAP_SIG_OP_DISCONN_RSP,
885 &req, sizeof(req)) == id);
886 }
887
888 static void
ble_l2cap_test_coc_invalid_disc_by_peer(struct test_data * t)889 ble_l2cap_test_coc_invalid_disc_by_peer(struct test_data *t)
890 {
891 struct ble_l2cap_sig_disc_req req;
892 uint8_t id = 10;
893 int rc;
894 struct event *ev = &t->event[t->event_iter++];
895
896 /* Receive disconnect request from peer. Note that source cid
897 * and destination cid are from peer perspective */
898 req.dcid = htole16(t->chan->scid);
899 req.scid = htole16(0);
900
901 rc = ble_hs_test_util_inject_rx_l2cap_sig(2, BLE_L2CAP_SIG_OP_DISCONN_REQ,
902 id, &req, sizeof(req));
903 TEST_ASSERT(rc == 0);
904
905 /* Ensure callback HAS NOT BEEN*/
906 TEST_ASSERT(!ev->handled);
907 }
908
909 static void
ble_l2cap_test_coc_send_data(struct test_data * t)910 ble_l2cap_test_coc_send_data(struct test_data *t)
911 {
912 struct os_mbuf *sdu;
913 struct os_mbuf *sdu_copy;
914 struct event *ev = &t->event[t->event_iter++];
915 int rc;
916
917 /* Send data event is created only for testing.
918 * Since application callback do caching of real stack event
919 * and checks the type of the event, lets increase event counter here and
920 * fake that this event is handled*/
921 t->event_cnt++;
922
923 sdu = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
924 assert(sdu != NULL);
925
926 sdu_copy = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
927 assert(sdu_copy != NULL);
928
929 rc = os_mbuf_append(sdu, ev->data, ev->data_len);
930 TEST_ASSERT(rc == 0);
931
932 rc = os_mbuf_append(sdu_copy, ev->data, ev->data_len);
933 TEST_ASSERT(rc == 0);
934
935 rc = ble_l2cap_send(t->chan, sdu);
936 TEST_ASSERT(rc == ev->early_error);
937
938 if (rc) {
939 rc = os_mbuf_free(sdu);
940 TEST_ASSERT_FATAL(rc == 0);
941
942 rc = os_mbuf_free(sdu_copy);
943 TEST_ASSERT_FATAL(rc == 0);
944 return;
945 }
946
947 /* Add place for SDU len */
948 sdu_copy = os_mbuf_prepend_pullup(sdu_copy, 2);
949 assert(sdu_copy != NULL);
950 put_le16(sdu_copy->om_data, ev->data_len);
951
952 ble_hs_test_util_verify_tx_l2cap(sdu);
953
954 rc = os_mbuf_free_chain(sdu_copy);
955 TEST_ASSERT_FATAL(rc == 0);
956 }
957
958 static void
ble_l2cap_test_coc_recv_data(struct test_data * t)959 ble_l2cap_test_coc_recv_data(struct test_data *t)
960 {
961 struct os_mbuf *sdu;
962 int rc;
963 struct event *ev = &t->event[t->event_iter++];
964
965 sdu = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
966 assert(sdu != NULL);
967
968 rc = os_mbuf_append(sdu, ev->data, ev->data_len);
969 TEST_ASSERT(rc == 0);
970
971 /* TODO handle fragmentation */
972
973 /* Add place for SDU len */
974 sdu = os_mbuf_prepend_pullup(sdu, 2);
975 assert(sdu != NULL);
976 put_le16(sdu->om_data, ev->data_len);
977
978 ble_hs_test_util_inject_rx_l2cap(2, t->chan->scid, sdu);
979 }
980
981 static void
ble_l2cap_test_set_chan_test_conf(uint16_t psm,uint16_t mtu,struct test_data * t)982 ble_l2cap_test_set_chan_test_conf(uint16_t psm, uint16_t mtu,
983 struct test_data *t)
984 {
985 memset(t, 0, sizeof(*t));
986
987 t->psm = psm;
988 t->mtu = mtu;
989 }
990
TEST_CASE(ble_l2cap_test_case_sig_coc_conn_invalid_psm)991 TEST_CASE(ble_l2cap_test_case_sig_coc_conn_invalid_psm)
992 {
993 struct test_data t;
994
995 ble_l2cap_test_util_init();
996 ble_l2cap_test_set_chan_test_conf(BLE_L2CAP_TEST_PSM,
997 BLE_L2CAP_TEST_COC_MTU, &t);
998 t.expected_num_of_ev = 1;
999
1000 t.event[0].type = BLE_L2CAP_EVENT_COC_CONNECTED;
1001 t.event[0].app_status = BLE_HS_ENOTSUP;
1002 t.event[0].l2cap_status = BLE_L2CAP_COC_ERR_UNKNOWN_LE_PSM;
1003
1004 ble_l2cap_test_coc_connect(&t);
1005
1006 TEST_ASSERT(t.expected_num_of_ev == t.event_iter);
1007 }
1008
TEST_CASE(ble_l2cap_test_case_sig_coc_conn_out_of_resource)1009 TEST_CASE(ble_l2cap_test_case_sig_coc_conn_out_of_resource)
1010 {
1011 struct test_data t;
1012
1013 ble_l2cap_test_util_init();
1014
1015 ble_l2cap_test_set_chan_test_conf(BLE_L2CAP_TEST_PSM,
1016 BLE_L2CAP_TEST_COC_MTU, &t);
1017 t.expected_num_of_ev = 1;
1018
1019 t.event[0].type = BLE_L2CAP_EVENT_COC_CONNECTED;
1020 t.event[0].app_status = BLE_HS_ENOMEM;
1021 t.event[0].l2cap_status = BLE_L2CAP_COC_ERR_NO_RESOURCES;
1022
1023 ble_l2cap_test_coc_connect(&t);
1024
1025 TEST_ASSERT(t.expected_num_of_ev == t.event_iter);
1026 }
1027
TEST_CASE(ble_l2cap_test_case_sig_coc_conn_invalid_cid)1028 TEST_CASE(ble_l2cap_test_case_sig_coc_conn_invalid_cid)
1029 {
1030 struct test_data t;
1031
1032 ble_l2cap_test_util_init();
1033
1034 ble_l2cap_test_set_chan_test_conf(BLE_L2CAP_TEST_PSM,
1035 BLE_L2CAP_TEST_COC_MTU, &t);
1036 t.expected_num_of_ev = 1;
1037
1038 t.event[0].type = BLE_L2CAP_EVENT_COC_CONNECTED;
1039 t.event[0].app_status = BLE_HS_EREJECT;
1040 t.event[0].l2cap_status = BLE_L2CAP_COC_ERR_INVALID_SOURCE_CID;
1041
1042 ble_l2cap_test_coc_connect(&t);
1043
1044 TEST_ASSERT(t.expected_num_of_ev == t.event_iter);
1045 }
1046
TEST_CASE(ble_l2cap_test_case_sig_coc_conn_insuff_authen)1047 TEST_CASE(ble_l2cap_test_case_sig_coc_conn_insuff_authen)
1048 {
1049 struct test_data t;
1050
1051 ble_l2cap_test_util_init();
1052
1053 ble_l2cap_test_set_chan_test_conf(BLE_L2CAP_TEST_PSM,
1054 BLE_L2CAP_TEST_COC_MTU, &t);
1055 t.expected_num_of_ev = 1;
1056
1057 t.event[0].type = BLE_L2CAP_EVENT_COC_CONNECTED;
1058 t.event[0].app_status = BLE_HS_EAUTHEN;
1059 t.event[0].l2cap_status = BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN;
1060
1061 ble_l2cap_test_coc_connect(&t);
1062
1063 TEST_ASSERT(t.expected_num_of_ev == t.event_iter);
1064 }
1065
TEST_CASE(ble_l2cap_test_case_sig_coc_conn_insuff_author)1066 TEST_CASE(ble_l2cap_test_case_sig_coc_conn_insuff_author)
1067 {
1068 struct test_data t;
1069
1070 ble_l2cap_test_util_init();
1071
1072 ble_l2cap_test_set_chan_test_conf(BLE_L2CAP_TEST_PSM,
1073 BLE_L2CAP_TEST_COC_MTU, &t);
1074 t.expected_num_of_ev = 1;
1075
1076 t.event[0].type = BLE_L2CAP_EVENT_COC_CONNECTED;
1077 t.event[0].app_status = BLE_HS_EAUTHOR;
1078 t.event[0].l2cap_status = BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR;
1079
1080 ble_l2cap_test_coc_connect(&t);
1081
1082 TEST_ASSERT(t.expected_num_of_ev == t.event_iter);
1083 }
1084
TEST_CASE(ble_l2cap_test_case_sig_coc_incoming_conn_invalid_psm)1085 TEST_CASE(ble_l2cap_test_case_sig_coc_incoming_conn_invalid_psm)
1086 {
1087 struct test_data t;
1088
1089 ble_l2cap_test_util_init();
1090
1091 ble_l2cap_test_set_chan_test_conf(BLE_L2CAP_TEST_PSM,
1092 BLE_L2CAP_TEST_COC_MTU, &t);
1093 t.expected_num_of_ev = 1;
1094
1095 t.event[0].type = BLE_L2CAP_EVENT_COC_CONNECTED;
1096 t.event[0].l2cap_status = BLE_L2CAP_COC_ERR_UNKNOWN_LE_PSM;
1097
1098 ble_l2cap_test_coc_connect_by_peer(&t);
1099
1100 TEST_ASSERT(t.expected_num_of_ev == t.event_iter);
1101 }
1102
TEST_CASE(ble_l2cap_test_case_sig_coc_incoming_conn_rejected_by_app)1103 TEST_CASE(ble_l2cap_test_case_sig_coc_incoming_conn_rejected_by_app)
1104 {
1105 struct test_data t;
1106 int rc;
1107
1108 ble_l2cap_test_util_init();
1109
1110 ble_l2cap_test_set_chan_test_conf(BLE_L2CAP_TEST_PSM,
1111 BLE_L2CAP_TEST_COC_MTU, &t);
1112 t.expected_num_of_ev = 2;
1113
1114 t.event[0].type = BLE_L2CAP_EVENT_COC_ACCEPT;
1115 t.event[0].app_status = BLE_HS_ENOMEM;
1116
1117 /* This event will not be called and test is going to verify it*/
1118 t.event[1].type = BLE_L2CAP_EVENT_COC_CONNECTED;
1119 t.event[1].l2cap_status = BLE_L2CAP_COC_ERR_NO_RESOURCES;
1120
1121 /* Register server */
1122 rc = ble_l2cap_create_server(t.psm, BLE_L2CAP_TEST_COC_MTU,
1123 ble_l2cap_test_event, &t);
1124 TEST_ASSERT(rc == 0);
1125
1126 ble_l2cap_test_coc_connect_by_peer(&t);
1127
1128 TEST_ASSERT(t.expected_num_of_ev == t.event_iter);
1129
1130 /* In this test case, L2CAP channel is created and once application rejects
1131 * connection, channel is destroyed. In such case CID for channel has been
1132 * used and we need to increase current_cid. */
1133 current_cid++;
1134 }
1135
TEST_CASE(ble_l2cap_test_case_sig_coc_incoming_conn_success)1136 TEST_CASE(ble_l2cap_test_case_sig_coc_incoming_conn_success)
1137 {
1138 struct test_data t;
1139 int rc;
1140
1141 ble_l2cap_test_util_init();
1142
1143 ble_l2cap_test_set_chan_test_conf(BLE_L2CAP_TEST_PSM,
1144 BLE_L2CAP_TEST_COC_MTU, &t);
1145 t.expected_num_of_ev = 2;
1146
1147 t.event[0].type = BLE_L2CAP_EVENT_COC_ACCEPT;
1148 t.event[1].type = BLE_L2CAP_EVENT_COC_CONNECTED;
1149
1150 /* Register server */
1151 rc = ble_l2cap_create_server(t.psm, BLE_L2CAP_TEST_COC_MTU,
1152 ble_l2cap_test_event, &t);
1153 TEST_ASSERT(rc == 0);
1154
1155 ble_l2cap_test_coc_connect_by_peer(&t);
1156
1157 TEST_ASSERT(t.expected_num_of_ev == t.event_iter);
1158 }
1159
TEST_CASE(ble_l2cap_test_case_sig_coc_disconnect_succeed)1160 TEST_CASE(ble_l2cap_test_case_sig_coc_disconnect_succeed)
1161 {
1162 struct test_data t;
1163
1164 ble_l2cap_test_util_init();
1165
1166 ble_l2cap_test_set_chan_test_conf(BLE_L2CAP_TEST_PSM,
1167 BLE_L2CAP_TEST_COC_MTU, &t);
1168 t. expected_num_of_ev = 2;
1169
1170 t.event[0].type = BLE_L2CAP_EVENT_COC_CONNECTED;
1171 t.event[0].app_status = 0;
1172 t.event[0].l2cap_status = BLE_L2CAP_COC_ERR_CONNECTION_SUCCESS;
1173 t.event[1].type = BLE_L2CAP_EVENT_COC_DISCONNECTED;
1174
1175 ble_l2cap_test_coc_connect(&t);
1176 ble_l2cap_test_coc_disc(&t);
1177
1178 TEST_ASSERT(t.expected_num_of_ev == t.event_iter);
1179 }
1180
TEST_CASE(ble_l2cap_test_case_sig_coc_incoming_disconnect_succeed)1181 TEST_CASE(ble_l2cap_test_case_sig_coc_incoming_disconnect_succeed)
1182 {
1183 struct test_data t;
1184
1185 ble_l2cap_test_util_init();
1186
1187 ble_l2cap_test_set_chan_test_conf(BLE_L2CAP_TEST_PSM,
1188 BLE_L2CAP_TEST_COC_MTU, &t);
1189 t.expected_num_of_ev = 2;
1190
1191 t.event[0].type = BLE_L2CAP_EVENT_COC_CONNECTED;
1192 t.event[0].app_status = 0;
1193 t.event[0].l2cap_status = BLE_L2CAP_COC_ERR_CONNECTION_SUCCESS;
1194 t.event[1].type = BLE_L2CAP_EVENT_COC_DISCONNECTED;
1195
1196 ble_l2cap_test_coc_connect(&t);
1197 ble_l2cap_test_coc_disc_by_peer(&t);
1198
1199 TEST_ASSERT(t.expected_num_of_ev == t.event_iter);
1200 }
1201
TEST_CASE(ble_l2cap_test_case_sig_coc_incoming_disconnect_failed)1202 TEST_CASE(ble_l2cap_test_case_sig_coc_incoming_disconnect_failed)
1203 {
1204 struct test_data t;
1205
1206 ble_l2cap_test_util_init();
1207
1208 ble_l2cap_test_set_chan_test_conf(BLE_L2CAP_TEST_PSM,
1209 BLE_L2CAP_TEST_COC_MTU, &t);
1210 t.expected_num_of_ev = 2;
1211
1212 t.event[0].type = BLE_L2CAP_EVENT_COC_CONNECTED;
1213 t.event[0].app_status = 0;
1214 t.event[0].l2cap_status = BLE_L2CAP_COC_ERR_CONNECTION_SUCCESS;
1215 t.event[1].type = BLE_L2CAP_EVENT_COC_DISCONNECTED;
1216
1217 ble_l2cap_test_coc_connect(&t);
1218 ble_l2cap_test_coc_invalid_disc_by_peer(&t);
1219
1220 TEST_ASSERT(t.expected_num_of_ev == t.event_iter);
1221 }
1222
TEST_CASE(ble_l2cap_test_case_coc_send_data_succeed)1223 TEST_CASE(ble_l2cap_test_case_coc_send_data_succeed)
1224 {
1225 struct test_data t;
1226 uint8_t buf[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
1227
1228 ble_l2cap_test_util_init();
1229
1230 ble_l2cap_test_set_chan_test_conf(BLE_L2CAP_TEST_PSM,
1231 BLE_L2CAP_TEST_COC_MTU, &t);
1232 t.expected_num_of_ev = 3;
1233
1234 t.event[0].type = BLE_L2CAP_TEST_EVENT_COC_CONNECT;
1235 t.event[1].type = BLE_L2CAP_TEST_EVENT_COC_SEND_DATA;
1236 t.event[1].data = buf;
1237 t.event[1].data_len = sizeof(buf);
1238 t.event[2].type = BLE_L2CAP_TEST_EVENT_COC_DISCONNECT;
1239
1240 ble_l2cap_test_coc_connect(&t);
1241 ble_l2cap_test_coc_send_data(&t);
1242 ble_l2cap_test_coc_disc(&t);
1243
1244 TEST_ASSERT(t.expected_num_of_ev == t.event_iter);
1245 }
1246
TEST_CASE(ble_l2cap_test_case_coc_send_data_failed_too_big_sdu)1247 TEST_CASE(ble_l2cap_test_case_coc_send_data_failed_too_big_sdu)
1248 {
1249 struct test_data t = {};
1250 uint16_t small_mtu = 27;
1251 uint8_t buf[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1252 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
1253
1254 ble_l2cap_test_util_init();
1255
1256 ble_l2cap_test_set_chan_test_conf(BLE_L2CAP_TEST_PSM, small_mtu, &t);
1257 t.expected_num_of_ev = 3;
1258
1259 t.event[0].type = BLE_L2CAP_TEST_EVENT_COC_CONNECT;
1260 t.event[1].type = BLE_L2CAP_TEST_EVENT_COC_SEND_DATA;
1261 t.event[1].data = buf;
1262 t.event[1].data_len = sizeof(buf);
1263 t.event[1].early_error = BLE_HS_EBADDATA;
1264 t.event[2].type = BLE_L2CAP_TEST_EVENT_COC_DISCONNECT;
1265
1266 ble_l2cap_test_coc_connect(&t);
1267 ble_l2cap_test_coc_send_data(&t);
1268 ble_l2cap_test_coc_disc(&t);
1269
1270 TEST_ASSERT(t.expected_num_of_ev == t.event_iter);
1271 }
1272
TEST_CASE(ble_l2cap_test_case_coc_recv_data_succeed)1273 TEST_CASE(ble_l2cap_test_case_coc_recv_data_succeed)
1274 {
1275 struct test_data t = {};
1276 uint8_t buf[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
1277
1278 ble_l2cap_test_util_init();
1279
1280 ble_l2cap_test_set_chan_test_conf(BLE_L2CAP_TEST_PSM,
1281 BLE_L2CAP_TEST_COC_MTU, &t);
1282 t.expected_num_of_ev = 3;
1283
1284 t.event[0].type = BLE_L2CAP_EVENT_COC_CONNECTED;
1285 t.event[1].type = BLE_L2CAP_EVENT_COC_DATA_RECEIVED;
1286 t.event[1].data = buf;
1287 t.event[1].data_len = sizeof(buf);
1288 t.event[2].type = BLE_L2CAP_EVENT_COC_DISCONNECTED;
1289
1290 ble_l2cap_test_coc_connect(&t);
1291 ble_l2cap_test_coc_recv_data(&t);
1292 ble_l2cap_test_coc_disc(&t);
1293
1294 TEST_ASSERT(t.expected_num_of_ev == t.event_iter);
1295 }
1296
TEST_SUITE(ble_l2cap_test_suite)1297 TEST_SUITE(ble_l2cap_test_suite)
1298 {
1299 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
1300
1301 ble_l2cap_test_case_bad_header();
1302 ble_l2cap_test_case_bad_handle();
1303 ble_l2cap_test_case_frag_single();
1304 ble_l2cap_test_case_frag_multiple();
1305 ble_l2cap_test_case_frag_channels();
1306 ble_l2cap_test_case_frag_timeout();
1307 ble_l2cap_test_case_sig_unsol_rsp();
1308 ble_l2cap_test_case_sig_update_accept();
1309 ble_l2cap_test_case_sig_update_reject();
1310 ble_l2cap_test_case_sig_update_init_accept();
1311 ble_l2cap_test_case_sig_update_init_reject();
1312 ble_l2cap_test_case_sig_update_init_fail_master();
1313 ble_l2cap_test_case_sig_update_init_fail_bad_id();
1314 ble_l2cap_test_case_sig_coc_conn_invalid_psm();
1315 ble_l2cap_test_case_sig_coc_conn_out_of_resource();
1316 ble_l2cap_test_case_sig_coc_conn_invalid_cid();
1317 ble_l2cap_test_case_sig_coc_conn_insuff_authen();
1318 ble_l2cap_test_case_sig_coc_conn_insuff_author();
1319 ble_l2cap_test_case_sig_coc_incoming_conn_invalid_psm();
1320 ble_l2cap_test_case_sig_coc_incoming_conn_rejected_by_app();
1321 ble_l2cap_test_case_sig_coc_incoming_conn_success();
1322 ble_l2cap_test_case_sig_coc_disconnect_succeed();
1323 ble_l2cap_test_case_sig_coc_incoming_disconnect_succeed();
1324 ble_l2cap_test_case_sig_coc_incoming_disconnect_failed();
1325 ble_l2cap_test_case_coc_send_data_succeed();
1326 ble_l2cap_test_case_coc_send_data_failed_too_big_sdu();
1327 ble_l2cap_test_case_coc_recv_data_succeed();
1328 }
1329
1330 int
ble_l2cap_test_all(void)1331 ble_l2cap_test_all(void)
1332 {
1333 ble_l2cap_test_suite();
1334
1335 return tu_any_failed;
1336 }
1337