1 /*
2 * Copyright (c) 2019 Alexander Wachter
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <zephyr/canbus/isotp.h>
7 #include <zephyr/drivers/can.h>
8 #include <zephyr/sys/util.h>
9 #include <zephyr/ztest.h>
10 #include <strings.h>
11 #include "random_data.h"
12
13 #if !defined(CONFIG_TEST_USE_CAN_FD_MODE) || CONFIG_TEST_ISOTP_TX_DL == 8
14 #define DATA_SIZE_SF 7
15 #define DATA_SIZE_CF 7
16 #define DATA_SIZE_SF_EXT 6
17 #define DATA_SIZE_FF 6
18 #define TX_DL 8
19 #define DATA_SEND_LENGTH 272
20 #define SF_PCI_BYTE_1 ((SF_PCI_TYPE << PCI_TYPE_POS) | DATA_SIZE_SF)
21 #define SF_PCI_BYTE_2_EXT ((SF_PCI_TYPE << PCI_TYPE_POS) | DATA_SIZE_SF_EXT)
22 #define SF_PCI_BYTE_LEN_8 ((SF_PCI_TYPE << PCI_TYPE_POS) | (DATA_SIZE_SF + 1))
23 #else
24 #define DATA_SIZE_SF (TX_DL - 2)
25 #define DATA_SIZE_CF (TX_DL - 1)
26 #define DATA_SIZE_SF_EXT (TX_DL - 3)
27 #define DATA_SIZE_FF (TX_DL - 2)
28 #define TX_DL CONFIG_TEST_ISOTP_TX_DL
29 /* Send length must be larger than FF + (8 * CF).
30 * But not so big that the remainder cannot fit into the buffers.
31 */
32 #define DATA_SEND_LENGTH (100 + DATA_SIZE_FF + (8 * DATA_SIZE_CF))
33 #define SF_PCI_BYTE_1 (SF_PCI_TYPE << PCI_TYPE_POS)
34 #define SF_PCI_BYTE_2 DATA_SIZE_SF
35 #define SF_PCI_BYTE_2_EXT (SF_PCI_TYPE << PCI_TYPE_POS)
36 #define SF_PCI_BYTE_3_EXT DATA_SIZE_SF_EXT
37 #endif
38
39 #define DATA_SIZE_FC 3
40 #define PCI_TYPE_POS 4
41 #define SF_PCI_TYPE 0
42 #define EXT_ADDR 5
43 #define FF_PCI_TYPE 1
44 #define FF_PCI_BYTE_1(dl) ((FF_PCI_TYPE << PCI_TYPE_POS) | ((dl) >> 8))
45 #define FF_PCI_BYTE_2(dl) ((dl) & 0xFF)
46 #define FC_PCI_TYPE 3
47 #define FC_PCI_CTS 0
48 #define FC_PCI_WAIT 1
49 #define FC_PCI_OVFLW 2
50 #define FC_PCI_BYTE_1(FS) ((FC_PCI_TYPE << PCI_TYPE_POS) | (FS))
51 #define FC_PCI_BYTE_2(BS) (BS)
52 #define FC_PCI_BYTE_3(ST_MIN) (ST_MIN)
53 #define CF_PCI_TYPE 2
54 #define CF_PCI_BYTE_1 (CF_PCI_TYPE << PCI_TYPE_POS)
55 #define STMIN_VAL_1 5
56 #define STMIN_VAL_2 50
57 #define STMIN_UPPER_TOLERANCE 5
58
59 #define BS_TIMEOUT_UPPER_MS 1100
60 #define BS_TIMEOUT_LOWER_MS 1000
61
62 /*
63 * @addtogroup t_can
64 * @{
65 * @defgroup t_can_isotp test_can_isotp
66 * @brief TestPurpose: verify correctness of the iso tp implementation
67 * @details
68 * - Test Steps
69 * -#
70 * - Expected Results
71 * -#
72 * @}
73 */
74
75 struct frame_desired {
76 uint8_t data[CAN_MAX_DLEN];
77 uint8_t length;
78 };
79
80 struct frame_desired des_frames[DIV_ROUND_UP((DATA_SEND_LENGTH - DATA_SIZE_FF),
81 DATA_SIZE_CF)];
82
83
84 const struct isotp_fc_opts fc_opts = {
85 .bs = 8,
86 .stmin = 0
87 };
88 const struct isotp_fc_opts fc_opts_single = {
89 .bs = 0,
90 .stmin = 0
91 };
92
93 const struct isotp_msg_id rx_addr = {
94 .std_id = 0x10,
95 #ifdef CONFIG_TEST_USE_CAN_FD_MODE
96 .dl = CONFIG_TEST_ISOTP_TX_DL,
97 .flags = ISOTP_MSG_FDF | ISOTP_MSG_BRS,
98 #endif
99 };
100 const struct isotp_msg_id tx_addr = {
101 .std_id = 0x11,
102 #ifdef CONFIG_TEST_USE_CAN_FD_MODE
103 .dl = CONFIG_TEST_ISOTP_TX_DL,
104 .flags = ISOTP_MSG_FDF | ISOTP_MSG_BRS,
105 #endif
106 };
107
108 const struct isotp_msg_id rx_addr_ext = {
109 .std_id = 0x10,
110 .ext_addr = EXT_ADDR,
111 #ifdef CONFIG_TEST_USE_CAN_FD_MODE
112 .dl = CONFIG_TEST_ISOTP_TX_DL,
113 .flags = ISOTP_MSG_EXT_ADDR | ISOTP_MSG_FDF | ISOTP_MSG_BRS,
114 #else
115 .flags = ISOTP_MSG_EXT_ADDR,
116 #endif
117 };
118
119 const struct isotp_msg_id tx_addr_ext = {
120 .std_id = 0x11,
121 .ext_addr = EXT_ADDR,
122 #ifdef CONFIG_TEST_USE_CAN_FD_MODE
123 .dl = CONFIG_TEST_ISOTP_TX_DL,
124 .flags = ISOTP_MSG_EXT_ADDR | ISOTP_MSG_FDF | ISOTP_MSG_BRS,
125 #else
126 .flags = ISOTP_MSG_EXT_ADDR,
127 #endif
128 };
129
130 const struct isotp_msg_id rx_addr_fixed = {
131 .ext_id = 0x18DA0201,
132 #ifdef CONFIG_TEST_USE_CAN_FD_MODE
133 .dl = CONFIG_TEST_ISOTP_TX_DL,
134 .flags = ISOTP_MSG_FIXED_ADDR | ISOTP_MSG_IDE | ISOTP_MSG_FDF | ISOTP_MSG_BRS,
135 #else
136 .flags = ISOTP_MSG_FIXED_ADDR | ISOTP_MSG_IDE,
137 #endif
138 };
139
140 const struct isotp_msg_id tx_addr_fixed = {
141 .ext_id = 0x18DA0102,
142 #ifdef CONFIG_TEST_USE_CAN_FD_MODE
143 .dl = CONFIG_TEST_ISOTP_TX_DL,
144 .flags = ISOTP_MSG_FIXED_ADDR | ISOTP_MSG_IDE | ISOTP_MSG_FDF | ISOTP_MSG_BRS,
145 #else
146 .flags = ISOTP_MSG_FIXED_ADDR | ISOTP_MSG_IDE,
147 #endif
148 };
149
150 static const struct device *const can_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus));
151 static struct isotp_recv_ctx recv_ctx;
152 static struct isotp_send_ctx send_ctx;
153 static uint8_t data_buf[128];
154 CAN_MSGQ_DEFINE(frame_msgq, 10);
155 static struct k_sem send_compl_sem;
156
send_complete_cb(int error_nr,void * arg)157 void send_complete_cb(int error_nr, void *arg)
158 {
159 int expected_err_nr = POINTER_TO_INT(arg);
160
161 zassert_equal(error_nr, expected_err_nr,
162 "Unexpected error nr. expect: %d, got %d",
163 expected_err_nr, error_nr);
164 k_sem_give(&send_compl_sem);
165 }
166
print_hex(const uint8_t * ptr,size_t len)167 static void print_hex(const uint8_t *ptr, size_t len)
168 {
169 while (len--) {
170 printk("%02x ", *ptr++);
171 }
172 }
173
174
check_data(const uint8_t * frame,const uint8_t * desired,size_t length)175 static int check_data(const uint8_t *frame, const uint8_t *desired, size_t length)
176 {
177 int ret;
178
179 ret = memcmp(frame, desired, length);
180 if (ret) {
181 printk("desired bytes:\n");
182 print_hex(desired, length);
183 printk("\nreceived (%zu bytes):\n", length);
184 print_hex(frame, length);
185 printk("\n");
186 }
187
188 return ret;
189 }
190
send_sf(void)191 static void send_sf(void)
192 {
193 int ret;
194
195 ret = isotp_send(&send_ctx, can_dev, random_data, DATA_SIZE_SF,
196 &rx_addr, &tx_addr, send_complete_cb, INT_TO_POINTER(ISOTP_N_OK));
197 zassert_equal(ret, 0, "Send returned %d", ret);
198 }
199
200
get_sf(size_t data_size)201 static void get_sf(size_t data_size)
202 {
203 int ret;
204
205 memset(data_buf, 0, sizeof(data_buf));
206 ret = isotp_recv(&recv_ctx, data_buf, sizeof(data_buf), K_MSEC(1000));
207 zassert_equal(ret, data_size, "recv returned %d", ret);
208
209 ret = check_data(data_buf, random_data, data_size);
210 zassert_equal(ret, 0, "Data differ");
211 }
212
get_sf_ignore(void)213 static void get_sf_ignore(void)
214 {
215 int ret;
216
217 ret = isotp_recv(&recv_ctx, data_buf, sizeof(data_buf), K_MSEC(200));
218 zassert_equal(ret, ISOTP_RECV_TIMEOUT, "recv returned %d", ret);
219 }
220
send_test_data(const uint8_t * data,size_t len)221 static void send_test_data(const uint8_t *data, size_t len)
222 {
223 int ret;
224
225 ret = isotp_send(&send_ctx, can_dev, data, len, &rx_addr, &tx_addr,
226 send_complete_cb, INT_TO_POINTER(ISOTP_N_OK));
227 zassert_equal(ret, 0, "Send returned %d", ret);
228 }
229
receive_test_data(const uint8_t * data,size_t len,int32_t delay)230 static void receive_test_data(const uint8_t *data, size_t len, int32_t delay)
231 {
232 size_t remaining_len = len;
233 int ret, recv_len;
234 const uint8_t *data_ptr = data;
235
236 do {
237 memset(data_buf, 0, sizeof(data_buf));
238 recv_len = isotp_recv(&recv_ctx, data_buf, sizeof(data_buf),
239 K_MSEC(1000));
240 zassert_true(recv_len >= 0, "recv error: %d", recv_len);
241
242 zassert_true(remaining_len >= recv_len,
243 "More data then expected");
244 ret = check_data(data_buf, data_ptr, recv_len);
245 zassert_equal(ret, 0, "Data differ");
246 data_ptr += recv_len;
247 remaining_len -= recv_len;
248
249 if (delay) {
250 k_msleep(delay);
251 }
252 } while (remaining_len);
253
254 ret = isotp_recv(&recv_ctx, data_buf, sizeof(data_buf), K_MSEC(50));
255 zassert_equal(ret, ISOTP_RECV_TIMEOUT,
256 "Expected timeout but got %d", ret);
257 }
258
send_frame_series(struct frame_desired * frames,size_t length,uint32_t id)259 static void send_frame_series(struct frame_desired *frames, size_t length,
260 uint32_t id)
261 {
262 int i, ret;
263 struct can_frame frame = {
264 .flags = ((id > 0x7FF) ? CAN_FRAME_IDE : 0) |
265 (IS_ENABLED(CONFIG_TEST_USE_CAN_FD_MODE) ?
266 CAN_FRAME_FDF | CAN_FRAME_BRS : 0),
267 .id = id
268 };
269 struct frame_desired *desired = frames;
270
271 for (i = 0; i < length; i++) {
272 frame.dlc = can_bytes_to_dlc(desired->length);
273 memcpy(frame.data, desired->data, desired->length);
274 ret = can_send(can_dev, &frame, K_MSEC(500), NULL, NULL);
275 zassert_equal(ret, 0, "Sending msg %d failed.", i);
276 desired++;
277 }
278 }
279
check_frame_series(struct frame_desired * frames,size_t length,struct k_msgq * msgq)280 static void check_frame_series(struct frame_desired *frames, size_t length,
281 struct k_msgq *msgq)
282 {
283 int i, ret;
284 struct can_frame frame;
285 struct frame_desired *desired = frames;
286
287 for (i = 0; i < length; i++) {
288 ret = k_msgq_get(msgq, &frame, K_MSEC(500));
289 zassert_equal(ret, 0, "Timeout waiting for msg nr %d. ret: %d",
290 i, ret);
291
292 zassert_equal(frame.dlc, can_bytes_to_dlc(desired->length),
293 "DLC of frame nr %d differ. Desired: %d, Got: %d",
294 i, can_bytes_to_dlc(desired->length), frame.dlc);
295
296 ret = check_data(frame.data, desired->data, desired->length);
297 zassert_equal(ret, 0, "Data differ");
298
299 desired++;
300 }
301 ret = k_msgq_get(msgq, &frame, K_MSEC(200));
302 zassert_equal(ret, -EAGAIN, "Expected timeout, but received %d", ret);
303 }
304
add_rx_msgq(uint32_t id,uint32_t mask)305 static int add_rx_msgq(uint32_t id, uint32_t mask)
306 {
307 int filter_id;
308 struct can_filter filter = {
309 .flags = (id > 0x7FF) ? CAN_FILTER_IDE : 0,
310 .id = id,
311 .mask = mask
312 };
313
314 filter_id = can_add_rx_filter_msgq(can_dev, &frame_msgq, &filter);
315 zassert_not_equal(filter_id, -ENOSPC, "Filter full");
316 zassert_true((filter_id >= 0), "Negative filter number [%d]",
317 filter_id);
318
319 return filter_id;
320 }
321
prepare_fc_frame(struct frame_desired * frame,uint8_t st,const struct isotp_fc_opts * opts,bool tx)322 static void prepare_fc_frame(struct frame_desired *frame, uint8_t st,
323 const struct isotp_fc_opts *opts, bool tx)
324 {
325 frame->data[0] = FC_PCI_BYTE_1(st);
326 frame->data[1] = FC_PCI_BYTE_2(opts->bs);
327 frame->data[2] = FC_PCI_BYTE_3(opts->stmin);
328 if ((IS_ENABLED(CONFIG_ISOTP_ENABLE_TX_PADDING) && tx) ||
329 (IS_ENABLED(CONFIG_ISOTP_REQUIRE_RX_PADDING) && !tx)) {
330 memset(&frame->data[DATA_SIZE_FC], 0xCC, 8 - DATA_SIZE_FC);
331 frame->length = 8;
332 } else {
333 frame->length = DATA_SIZE_FC;
334 }
335 }
336
prepare_sf_frame(struct frame_desired * frame,const uint8_t * data)337 static void prepare_sf_frame(struct frame_desired *frame, const uint8_t *data)
338 {
339 frame->data[0] = SF_PCI_BYTE_1;
340 #ifdef SF_PCI_BYTE_2
341 frame->data[1] = SF_PCI_BYTE_2;
342 memcpy(&frame->data[2], data, DATA_SIZE_SF);
343 frame->length = DATA_SIZE_SF + 2;
344 #else
345 memcpy(&frame->data[1], data, DATA_SIZE_SF);
346 frame->length = DATA_SIZE_SF + 1;
347 #endif
348 }
349
prepare_sf_ext_frame(struct frame_desired * frame,const uint8_t * data)350 static void prepare_sf_ext_frame(struct frame_desired *frame, const uint8_t *data)
351 {
352 frame->data[0] = rx_addr_ext.ext_addr;
353 frame->data[1] = SF_PCI_BYTE_2_EXT;
354 #ifdef SF_PCI_BYTE_3_EXT
355 frame->data[2] = SF_PCI_BYTE_3_EXT;
356 memcpy(&frame->data[3], data, DATA_SIZE_SF_EXT);
357 frame->length = DATA_SIZE_SF_EXT + 3;
358 #else
359 memcpy(&frame->data[2], data, DATA_SIZE_SF_EXT);
360 frame->length = DATA_SIZE_SF_EXT + 2;
361 #endif
362 }
363
prepare_cf_frames(struct frame_desired * frames,size_t frames_cnt,const uint8_t * data,size_t data_len,bool tx)364 static void prepare_cf_frames(struct frame_desired *frames, size_t frames_cnt,
365 const uint8_t *data, size_t data_len, bool tx)
366 {
367 int i;
368 const uint8_t *data_ptr = data;
369 size_t remaining_length = data_len;
370
371 for (i = 0; i < frames_cnt && remaining_length; i++) {
372 frames[i].data[0] = CF_PCI_BYTE_1 | ((i+1) & 0x0F);
373 frames[i].length = TX_DL;
374 memcpy(&frames[i].data[1], data_ptr, DATA_SIZE_CF);
375
376 if (remaining_length < DATA_SIZE_CF) {
377 if ((IS_ENABLED(CONFIG_ISOTP_ENABLE_TX_PADDING) && tx) ||
378 (IS_ENABLED(CONFIG_ISOTP_REQUIRE_RX_PADDING) && !tx)) {
379 uint8_t padded_dlc = can_bytes_to_dlc(MAX(8, remaining_length + 1));
380 uint8_t padded_len = can_dlc_to_bytes(padded_dlc);
381
382 memset(&frames[i].data[remaining_length + 1], 0xCC,
383 padded_len - remaining_length - 1);
384 frames[i].length = padded_len;
385 } else {
386 frames[i].length = remaining_length + 1;
387 }
388 remaining_length = 0;
389 }
390
391 remaining_length -= DATA_SIZE_CF;
392 data_ptr += DATA_SIZE_CF;
393 }
394 }
395
ZTEST(isotp_conformance,test_send_sf)396 ZTEST(isotp_conformance, test_send_sf)
397 {
398 int filter_id;
399 struct frame_desired des_frame;
400
401 prepare_sf_frame(&des_frame, random_data);
402
403 filter_id = add_rx_msgq(rx_addr.std_id, CAN_STD_ID_MASK);
404 zassert_true((filter_id >= 0), "Negative filter number [%d]",
405 filter_id);
406
407 send_sf();
408
409 check_frame_series(&des_frame, 1, &frame_msgq);
410
411 can_remove_rx_filter(can_dev, filter_id);
412 }
413
ZTEST(isotp_conformance,test_receive_sf)414 ZTEST(isotp_conformance, test_receive_sf)
415 {
416 int ret;
417 struct frame_desired single_frame;
418
419 prepare_sf_frame(&single_frame, random_data);
420
421 ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
422 &fc_opts_single, K_NO_WAIT);
423 zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret);
424
425 send_frame_series(&single_frame, 1, rx_addr.std_id);
426
427 get_sf(DATA_SIZE_SF);
428
429 /* Frame size too big should be ignored/dropped */
430 #ifdef SF_PCI_BYTE_2
431 single_frame.data[1]++;
432 #else
433 single_frame.data[0] = SF_PCI_BYTE_LEN_8;
434 #endif
435 send_frame_series(&single_frame, 1, rx_addr.std_id);
436 get_sf_ignore();
437
438 #ifdef CONFIG_ISOTP_REQUIRE_RX_PADDING
439 single_frame.data[0] = SF_PCI_BYTE_1;
440 single_frame.length = 7;
441 send_frame_series(&single_frame, 1, rx_addr.std_id);
442
443 get_sf_ignore();
444 #endif
445
446 isotp_unbind(&recv_ctx);
447 }
448
ZTEST(isotp_conformance,test_send_sf_ext)449 ZTEST(isotp_conformance, test_send_sf_ext)
450 {
451 int filter_id, ret;
452 struct frame_desired des_frame;
453
454 prepare_sf_ext_frame(&des_frame, random_data);
455
456 filter_id = add_rx_msgq(rx_addr_ext.std_id, CAN_STD_ID_MASK);
457 zassert_true((filter_id >= 0), "Negative filter number [%d]",
458 filter_id);
459
460 ret = isotp_send(&send_ctx, can_dev, random_data, DATA_SIZE_SF_EXT,
461 &rx_addr_ext, &tx_addr_ext, send_complete_cb,
462 INT_TO_POINTER(ISOTP_N_OK));
463 zassert_equal(ret, 0, "Send returned %d", ret);
464
465 check_frame_series(&des_frame, 1, &frame_msgq);
466
467 can_remove_rx_filter(can_dev, filter_id);
468 }
469
ZTEST(isotp_conformance,test_receive_sf_ext)470 ZTEST(isotp_conformance, test_receive_sf_ext)
471 {
472 int ret;
473 struct frame_desired single_frame;
474
475 prepare_sf_ext_frame(&single_frame, random_data);
476
477 ret = isotp_bind(&recv_ctx, can_dev, &rx_addr_ext, &tx_addr,
478 &fc_opts_single, K_NO_WAIT);
479 zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret);
480
481 send_frame_series(&single_frame, 1, rx_addr.std_id);
482
483 get_sf(DATA_SIZE_SF_EXT);
484
485 /* Frame size too big should be ignored/dropped */
486 #ifdef SF_PCI_BYTE_2
487 single_frame.data[2]++;
488 #else
489 single_frame.data[1] = SF_PCI_BYTE_1;
490 #endif
491 send_frame_series(&single_frame, 1, rx_addr.std_id);
492 get_sf_ignore();
493
494 #ifdef CONFIG_ISOTP_REQUIRE_RX_PADDING
495 single_frame.data[1] = SF_PCI_BYTE_2_EXT;
496 single_frame.length = 7;
497 send_frame_series(&single_frame, 1, rx_addr.std_id);
498
499 get_sf_ignore();
500 #endif
501
502 isotp_unbind(&recv_ctx);
503 }
504
ZTEST(isotp_conformance,test_send_sf_fixed)505 ZTEST(isotp_conformance, test_send_sf_fixed)
506 {
507 int filter_id, ret;
508 struct frame_desired des_frame;
509
510 prepare_sf_frame(&des_frame, random_data);
511
512 /* mask to allow any priority and source address (SA) */
513 filter_id = add_rx_msgq(rx_addr_fixed.ext_id, 0x03FFFF00);
514 zassert_true((filter_id >= 0), "Negative filter number [%d]",
515 filter_id);
516
517 ret = isotp_send(&send_ctx, can_dev, random_data, DATA_SIZE_SF,
518 &rx_addr_fixed, &tx_addr_fixed, send_complete_cb,
519 INT_TO_POINTER(ISOTP_N_OK));
520 zassert_equal(ret, 0, "Send returned %d", ret);
521
522 check_frame_series(&des_frame, 1, &frame_msgq);
523
524 can_remove_rx_filter(can_dev, filter_id);
525 }
526
ZTEST(isotp_conformance,test_receive_sf_fixed)527 ZTEST(isotp_conformance, test_receive_sf_fixed)
528 {
529 int ret;
530 struct frame_desired single_frame;
531
532 prepare_sf_frame(&single_frame, random_data);
533
534 ret = isotp_bind(&recv_ctx, can_dev, &rx_addr_fixed, &tx_addr_fixed,
535 &fc_opts_single, K_NO_WAIT);
536 zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret);
537
538 /* default source address */
539 send_frame_series(&single_frame, 1, rx_addr_fixed.ext_id);
540 get_sf(DATA_SIZE_SF);
541
542 /* different source address */
543 send_frame_series(&single_frame, 1, rx_addr_fixed.ext_id | 0xFF);
544 get_sf(DATA_SIZE_SF);
545
546 /* different priority */
547 send_frame_series(&single_frame, 1, rx_addr_fixed.ext_id | (7U << 26));
548 get_sf(DATA_SIZE_SF);
549
550 /* different target address (should fail) */
551 send_frame_series(&single_frame, 1, rx_addr_fixed.ext_id | 0xFF00);
552 get_sf_ignore();
553
554 isotp_unbind(&recv_ctx);
555 }
556
ZTEST(isotp_conformance,test_send_data)557 ZTEST(isotp_conformance, test_send_data)
558 {
559 struct frame_desired fc_frame, ff_frame;
560 const uint8_t *data_ptr = random_data;
561 size_t remaining_length = DATA_SEND_LENGTH;
562 int filter_id;
563
564 ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SEND_LENGTH);
565 ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SEND_LENGTH);
566 memcpy(&ff_frame.data[2], data_ptr, DATA_SIZE_FF);
567 ff_frame.length = TX_DL;
568 data_ptr += DATA_SIZE_FF;
569 remaining_length -= DATA_SIZE_FF;
570
571 prepare_fc_frame(&fc_frame, FC_PCI_CTS, &fc_opts_single, false);
572
573 prepare_cf_frames(des_frames, ARRAY_SIZE(des_frames), data_ptr,
574 remaining_length, true);
575
576 filter_id = add_rx_msgq(rx_addr.std_id, CAN_STD_ID_MASK);
577 zassert_true((filter_id >= 0), "Negative filter number [%d]",
578 filter_id);
579
580 send_test_data(random_data, DATA_SEND_LENGTH);
581
582 check_frame_series(&ff_frame, 1, &frame_msgq);
583
584 send_frame_series(&fc_frame, 1, tx_addr.std_id);
585
586 check_frame_series(des_frames, ARRAY_SIZE(des_frames), &frame_msgq);
587
588 can_remove_rx_filter(can_dev, filter_id);
589 }
590
ZTEST(isotp_conformance,test_send_data_blocks)591 ZTEST(isotp_conformance, test_send_data_blocks)
592 {
593 const uint8_t *data_ptr = random_data;
594 size_t remaining_length = DATA_SEND_LENGTH;
595 struct frame_desired *data_frame_ptr = des_frames;
596 int filter_id, ret;
597 struct can_frame dummy_frame;
598 struct frame_desired fc_frame, ff_frame;
599
600 ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SEND_LENGTH);
601 ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SEND_LENGTH);
602 memcpy(&ff_frame.data[2], data_ptr, DATA_SIZE_FF);
603 ff_frame.length = DATA_SIZE_FF + 2;
604 data_ptr += DATA_SIZE_FF;
605 remaining_length -= DATA_SIZE_FF;
606
607 prepare_fc_frame(&fc_frame, FC_PCI_CTS, &fc_opts, false);
608
609 prepare_cf_frames(des_frames, ARRAY_SIZE(des_frames), data_ptr,
610 remaining_length, true);
611
612 remaining_length = DATA_SEND_LENGTH;
613
614 filter_id = add_rx_msgq(rx_addr.std_id, CAN_STD_ID_MASK);
615 zassert_true((filter_id >= 0), "Negative filter number [%d]",
616 filter_id);
617
618 send_test_data(random_data, DATA_SEND_LENGTH);
619
620 check_frame_series(&ff_frame, 1, &frame_msgq);
621 remaining_length -= DATA_SIZE_FF;
622
623 send_frame_series(&fc_frame, 1, tx_addr.std_id);
624
625 check_frame_series(data_frame_ptr, fc_opts.bs, &frame_msgq);
626 data_frame_ptr += fc_opts.bs;
627 remaining_length -= fc_opts.bs * DATA_SIZE_CF;
628 ret = k_msgq_get(&frame_msgq, &dummy_frame, K_MSEC(50));
629 zassert_equal(ret, -EAGAIN, "Expected timeout but got %d", ret);
630
631 fc_frame.data[1] = FC_PCI_BYTE_2(2);
632 send_frame_series(&fc_frame, 1, tx_addr.std_id);
633
634 /* dynamic bs */
635 check_frame_series(data_frame_ptr, 2, &frame_msgq);
636 data_frame_ptr += 2;
637 remaining_length -= 2 * DATA_SIZE_CF;
638 ret = k_msgq_get(&frame_msgq, &dummy_frame, K_MSEC(50));
639 zassert_equal(ret, -EAGAIN, "Expected timeout but got %d", ret);
640
641 /* get the rest */
642 fc_frame.data[1] = FC_PCI_BYTE_2(0);
643 send_frame_series(&fc_frame, 1, tx_addr.std_id);
644
645 check_frame_series(data_frame_ptr,
646 DIV_ROUND_UP(remaining_length, DATA_SIZE_CF),
647 &frame_msgq);
648 ret = k_msgq_get(&frame_msgq, &dummy_frame, K_MSEC(50));
649 zassert_equal(ret, -EAGAIN, "Expected timeout but got %d", ret);
650
651 can_remove_rx_filter(can_dev, filter_id);
652 }
653
ZTEST(isotp_conformance,test_receive_data)654 ZTEST(isotp_conformance, test_receive_data)
655 {
656 const uint8_t *data_ptr = random_data;
657 size_t remaining_length = DATA_SEND_LENGTH;
658 int filter_id, ret;
659 struct frame_desired fc_frame, ff_frame;
660
661 ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SEND_LENGTH);
662 ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SEND_LENGTH);
663 memcpy(&ff_frame.data[2], data_ptr, DATA_SIZE_FF);
664 ff_frame.length = TX_DL;
665 data_ptr += DATA_SIZE_FF;
666 remaining_length -= DATA_SIZE_FF;
667
668 prepare_fc_frame(&fc_frame, FC_PCI_CTS, &fc_opts_single, true);
669
670 prepare_cf_frames(des_frames, ARRAY_SIZE(des_frames), data_ptr,
671 remaining_length, false);
672
673 filter_id = add_rx_msgq(tx_addr.std_id, CAN_STD_ID_MASK);
674
675 ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
676 &fc_opts_single, K_NO_WAIT);
677 zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret);
678
679 send_frame_series(&ff_frame, 1, rx_addr.std_id);
680
681 check_frame_series(&fc_frame, 1, &frame_msgq);
682
683 send_frame_series(des_frames, ARRAY_SIZE(des_frames), rx_addr.std_id);
684
685 receive_test_data(random_data, DATA_SEND_LENGTH, 0);
686
687 can_remove_rx_filter(can_dev, filter_id);
688 isotp_unbind(&recv_ctx);
689 }
690
ZTEST(isotp_conformance,test_receive_data_blocks)691 ZTEST(isotp_conformance, test_receive_data_blocks)
692 {
693 const uint8_t *data_ptr = random_data;
694 size_t remaining_length = DATA_SEND_LENGTH;
695 struct frame_desired *data_frame_ptr = des_frames;
696 int filter_id, ret;
697 size_t remaining_frames;
698 struct frame_desired fc_frame, ff_frame;
699
700 struct can_frame dummy_frame;
701
702 ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SEND_LENGTH);
703 ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SEND_LENGTH);
704 memcpy(&ff_frame.data[2], data_ptr, DATA_SIZE_FF);
705 ff_frame.length = DATA_SIZE_FF + 2;
706 data_ptr += DATA_SIZE_FF;
707 remaining_length -= DATA_SIZE_FF;
708
709 prepare_fc_frame(&fc_frame, FC_PCI_CTS, &fc_opts, true);
710
711 prepare_cf_frames(des_frames, ARRAY_SIZE(des_frames), data_ptr,
712 remaining_length, false);
713
714 remaining_frames = DIV_ROUND_UP(remaining_length, DATA_SIZE_CF);
715
716 filter_id = add_rx_msgq(tx_addr.std_id, CAN_STD_ID_MASK);
717 zassert_true((filter_id >= 0), "Negative filter number [%d]",
718 filter_id);
719
720 ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
721 &fc_opts, K_NO_WAIT);
722 zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret);
723
724 send_frame_series(&ff_frame, 1, rx_addr.std_id);
725
726 while (remaining_frames) {
727 check_frame_series(&fc_frame, 1, &frame_msgq);
728
729 if (remaining_frames >= fc_opts.bs) {
730 send_frame_series(data_frame_ptr, fc_opts.bs,
731 rx_addr.std_id);
732 data_frame_ptr += fc_opts.bs;
733 remaining_frames -= fc_opts.bs;
734 } else {
735 send_frame_series(data_frame_ptr, remaining_frames,
736 rx_addr.std_id);
737 data_frame_ptr += remaining_frames;
738 remaining_frames = 0;
739 }
740 }
741
742 ret = k_msgq_get(&frame_msgq, &dummy_frame, K_MSEC(50));
743 zassert_equal(ret, -EAGAIN, "Expected timeout but got %d", ret);
744
745 receive_test_data(random_data, DATA_SEND_LENGTH, 0);
746
747 can_remove_rx_filter(can_dev, filter_id);
748 isotp_unbind(&recv_ctx);
749 }
750
ZTEST(isotp_conformance,test_send_timeouts)751 ZTEST(isotp_conformance, test_send_timeouts)
752 {
753 int ret;
754 uint32_t start_time, time_diff;
755 struct frame_desired fc_cts_frame;
756
757 prepare_fc_frame(&fc_cts_frame, FC_PCI_CTS, &fc_opts, false);
758
759 /* Test timeout for first FC*/
760 start_time = k_uptime_get_32();
761 ret = isotp_send(&send_ctx, can_dev, random_data, sizeof(random_data),
762 &tx_addr, &rx_addr, NULL, NULL);
763 time_diff = k_uptime_get_32() - start_time;
764 zassert_equal(ret, ISOTP_N_TIMEOUT_BS, "Expected timeout but got %d",
765 ret);
766 zassert_true(time_diff <= BS_TIMEOUT_UPPER_MS,
767 "Timeout too late (%dms)", time_diff);
768 zassert_true(time_diff >= BS_TIMEOUT_LOWER_MS,
769 "Timeout too early (%dms)", time_diff);
770
771 /* Test timeout for consecutive FC frames */
772 k_sem_reset(&send_compl_sem);
773 ret = isotp_send(&send_ctx, can_dev, random_data, sizeof(random_data),
774 &tx_addr, &rx_addr, send_complete_cb,
775 INT_TO_POINTER(ISOTP_N_TIMEOUT_BS));
776 zassert_equal(ret, ISOTP_N_OK, "Send returned %d", ret);
777
778 send_frame_series(&fc_cts_frame, 1, rx_addr.std_id);
779
780 start_time = k_uptime_get_32();
781 ret = k_sem_take(&send_compl_sem, K_MSEC(BS_TIMEOUT_UPPER_MS));
782 zassert_equal(ret, 0, "Timeout too late");
783
784 time_diff = k_uptime_get_32() - start_time;
785 zassert_true(time_diff >= BS_TIMEOUT_LOWER_MS,
786 "Timeout too early (%dms)", time_diff);
787
788 /* Test timeout reset with WAIT frame */
789 k_sem_reset(&send_compl_sem);
790 ret = isotp_send(&send_ctx, can_dev, random_data, sizeof(random_data),
791 &tx_addr, &rx_addr, send_complete_cb,
792 INT_TO_POINTER(ISOTP_N_TIMEOUT_BS));
793 zassert_equal(ret, ISOTP_N_OK, "Send returned %d", ret);
794
795 ret = k_sem_take(&send_compl_sem, K_MSEC(800));
796 zassert_equal(ret, -EAGAIN, "Timeout too early");
797
798 fc_cts_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_CTS);
799 send_frame_series(&fc_cts_frame, 1, rx_addr.std_id);
800
801 start_time = k_uptime_get_32();
802 ret = k_sem_take(&send_compl_sem, K_MSEC(BS_TIMEOUT_UPPER_MS));
803 zassert_equal(ret, 0, "Timeout too late");
804 time_diff = k_uptime_get_32() - start_time;
805 zassert_true(time_diff >= BS_TIMEOUT_LOWER_MS,
806 "Timeout too early (%dms)", time_diff);
807 }
808
ZTEST(isotp_conformance,test_receive_timeouts)809 ZTEST(isotp_conformance, test_receive_timeouts)
810 {
811 int ret;
812 uint32_t start_time, time_diff;
813 struct frame_desired ff_frame;
814
815 ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SEND_LENGTH);
816 ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SEND_LENGTH);
817 memcpy(&ff_frame.data[2], random_data, DATA_SIZE_FF);
818 ff_frame.length = DATA_SIZE_FF + 2;
819
820 ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
821 &fc_opts, K_NO_WAIT);
822 zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret);
823
824 send_frame_series(&ff_frame, 1, rx_addr.std_id);
825 start_time = k_uptime_get_32();
826
827 ret = isotp_recv(&recv_ctx, data_buf, sizeof(data_buf), K_FOREVER);
828 zassert_equal(ret, DATA_SIZE_FF,
829 "Expected FF data length but got %d", ret);
830 ret = isotp_recv(&recv_ctx, data_buf, sizeof(data_buf), K_FOREVER);
831 zassert_equal(ret, ISOTP_N_TIMEOUT_CR,
832 "Expected timeout but got %d", ret);
833
834 time_diff = k_uptime_get_32() - start_time;
835 zassert_true(time_diff >= BS_TIMEOUT_LOWER_MS,
836 "Timeout too early (%dms)", time_diff);
837 zassert_true(time_diff <= BS_TIMEOUT_UPPER_MS,
838 "Timeout too slow (%dms)", time_diff);
839
840 isotp_unbind(&recv_ctx);
841 }
842
ZTEST(isotp_conformance,test_stmin)843 ZTEST(isotp_conformance, test_stmin)
844 {
845 int filter_id, ret;
846 struct frame_desired fc_frame, ff_frame;
847 struct can_frame raw_frame;
848 uint32_t start_time, time_diff;
849 struct isotp_fc_opts fc_opts_stmin = {
850 .bs = 2, .stmin = STMIN_VAL_1
851 };
852
853 if (CONFIG_SYS_CLOCK_TICKS_PER_SEC < 1000) {
854 /* This test requires millisecond tick resolution */
855 ztest_test_skip();
856 }
857
858 ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SIZE_FF + DATA_SIZE_CF * 4);
859 ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SIZE_FF + DATA_SIZE_CF * 4);
860 memcpy(&ff_frame.data[2], random_data, DATA_SIZE_FF);
861 ff_frame.length = DATA_SIZE_FF + 2;
862
863 prepare_fc_frame(&fc_frame, FC_PCI_CTS, &fc_opts_stmin, false);
864
865 filter_id = add_rx_msgq(rx_addr.std_id, CAN_STD_ID_MASK);
866 zassert_true((filter_id >= 0), "Negative filter number [%d]",
867 filter_id);
868
869 send_test_data(random_data, DATA_SIZE_FF + DATA_SIZE_CF * 4);
870
871 check_frame_series(&ff_frame, 1, &frame_msgq);
872
873 send_frame_series(&fc_frame, 1, tx_addr.std_id);
874
875 ret = k_msgq_get(&frame_msgq, &raw_frame, K_MSEC(100));
876 zassert_equal(ret, 0, "Expected to get a message. [%d]", ret);
877
878 start_time = k_uptime_get_32();
879 ret = k_msgq_get(&frame_msgq, &raw_frame,
880 K_MSEC(STMIN_VAL_1 + STMIN_UPPER_TOLERANCE));
881 time_diff = k_uptime_get_32() - start_time;
882 zassert_equal(ret, 0, "Expected to get a message within %dms. [%d]",
883 STMIN_VAL_1 + STMIN_UPPER_TOLERANCE, ret);
884 zassert_true(time_diff >= STMIN_VAL_1, "STmin too short (%dms)",
885 time_diff);
886
887 fc_frame.data[2] = FC_PCI_BYTE_3(STMIN_VAL_2);
888 send_frame_series(&fc_frame, 1, tx_addr.std_id);
889
890 ret = k_msgq_get(&frame_msgq, &raw_frame, K_MSEC(100));
891 zassert_equal(ret, 0, "Expected to get a message. [%d]", ret);
892
893 start_time = k_uptime_get_32();
894 ret = k_msgq_get(&frame_msgq, &raw_frame,
895 K_MSEC(STMIN_VAL_2 + STMIN_UPPER_TOLERANCE));
896 time_diff = k_uptime_get_32() - start_time;
897 zassert_equal(ret, 0, "Expected to get a message within %dms. [%d]",
898 STMIN_VAL_2 + STMIN_UPPER_TOLERANCE, ret);
899 zassert_true(time_diff >= STMIN_VAL_2, "STmin too short (%dms)",
900 time_diff);
901
902 can_remove_rx_filter(can_dev, filter_id);
903 }
904
ZTEST(isotp_conformance,test_receiver_fc_errors)905 ZTEST(isotp_conformance, test_receiver_fc_errors)
906 {
907 int ret, filter_id;
908 struct frame_desired ff_frame, fc_frame;
909
910 ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SEND_LENGTH);
911 ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SEND_LENGTH);
912 memcpy(&ff_frame.data[2], random_data, DATA_SIZE_FF);
913 ff_frame.length = DATA_SIZE_FF + 2;
914
915 prepare_fc_frame(&fc_frame, FC_PCI_CTS, &fc_opts, true);
916
917 filter_id = add_rx_msgq(tx_addr.std_id, CAN_STD_ID_MASK);
918 zassert_true((filter_id >= 0), "Negative filter number [%d]",
919 filter_id);
920
921 ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
922 &fc_opts, K_NO_WAIT);
923 zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret);
924
925 /* wrong sequence number */
926 send_frame_series(&ff_frame, 1, rx_addr.std_id);
927 check_frame_series(&fc_frame, 1, &frame_msgq);
928 prepare_cf_frames(des_frames, ARRAY_SIZE(des_frames),
929 random_data + DATA_SIZE_FF,
930 sizeof(random_data) - DATA_SIZE_FF, false);
931 /* SN should be 2 but is set to 3 for this test */
932 des_frames[1].data[0] = CF_PCI_BYTE_1 | (3 & 0x0F);
933 send_frame_series(des_frames, fc_opts.bs, rx_addr.std_id);
934
935 ret = isotp_recv(&recv_ctx, data_buf, sizeof(data_buf), K_MSEC(200));
936 zassert_equal(ret, DATA_SIZE_FF,
937 "Expected FF data length but got %d", ret);
938 ret = isotp_recv(&recv_ctx, data_buf, sizeof(data_buf), K_MSEC(200));
939 zassert_equal(ret, ISOTP_N_WRONG_SN,
940 "Expected wrong SN but got %d", ret);
941
942 /* buffer overflow */
943 ff_frame.data[0] = FF_PCI_BYTE_1(0xFFF);
944 ff_frame.data[1] = FF_PCI_BYTE_2(0xFFF);
945
946 fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_OVFLW);
947 fc_frame.data[1] = FC_PCI_BYTE_2(0);
948 fc_frame.data[2] = FC_PCI_BYTE_3(0);
949
950 isotp_unbind(&recv_ctx);
951 ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
952 &fc_opts_single, K_NO_WAIT);
953 zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret);
954
955 send_frame_series(&ff_frame, 1, rx_addr.std_id);
956 check_frame_series(&fc_frame, 1, &frame_msgq);
957
958 can_remove_rx_filter(can_dev, filter_id);
959 k_msgq_cleanup(&frame_msgq);
960 isotp_unbind(&recv_ctx);
961 }
962
ZTEST(isotp_conformance,test_sender_fc_errors)963 ZTEST(isotp_conformance, test_sender_fc_errors)
964 {
965 int ret, filter_id, i;
966 struct frame_desired ff_frame, fc_frame;
967
968 ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SEND_LENGTH);
969 ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SEND_LENGTH);
970 memcpy(&ff_frame.data[2], random_data, DATA_SIZE_FF);
971 ff_frame.length = DATA_SIZE_FF + 2;
972
973 filter_id = add_rx_msgq(tx_addr.std_id, CAN_STD_ID_MASK);
974
975 /* invalid flow status */
976 prepare_fc_frame(&fc_frame, 3, &fc_opts, false);
977
978 k_sem_reset(&send_compl_sem);
979 ret = isotp_send(&send_ctx, can_dev, random_data, DATA_SEND_LENGTH,
980 &tx_addr, &rx_addr, send_complete_cb,
981 INT_TO_POINTER(ISOTP_N_INVALID_FS));
982 zassert_equal(ret, ISOTP_N_OK, "Send returned %d", ret);
983
984 check_frame_series(&ff_frame, 1, &frame_msgq);
985 send_frame_series(&fc_frame, 1, rx_addr.std_id);
986 ret = k_sem_take(&send_compl_sem, K_MSEC(200));
987 zassert_equal(ret, 0, "Send complete callback not called");
988
989 /* buffer overflow */
990 k_sem_reset(&send_compl_sem);
991 ret = isotp_send(&send_ctx, can_dev, random_data, DATA_SEND_LENGTH,
992 &tx_addr, &rx_addr, send_complete_cb,
993 INT_TO_POINTER(ISOTP_N_BUFFER_OVERFLW));
994
995 check_frame_series(&ff_frame, 1, &frame_msgq);
996 fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_OVFLW);
997 send_frame_series(&fc_frame, 1, rx_addr.std_id);
998 ret = k_sem_take(&send_compl_sem, K_MSEC(200));
999 zassert_equal(ret, 0, "Send complete callback not called");
1000
1001 /* wft overrun */
1002 k_sem_reset(&send_compl_sem);
1003 ret = isotp_send(&send_ctx, can_dev, random_data, DATA_SEND_LENGTH,
1004 &tx_addr, &rx_addr, send_complete_cb,
1005 INT_TO_POINTER(ISOTP_N_WFT_OVRN));
1006
1007 check_frame_series(&ff_frame, 1, &frame_msgq);
1008 fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_WAIT);
1009 for (i = 0; i < CONFIG_ISOTP_WFTMAX + 1; i++) {
1010 send_frame_series(&fc_frame, 1, rx_addr.std_id);
1011 }
1012
1013 ret = k_sem_take(&send_compl_sem, K_MSEC(200));
1014 zassert_equal(ret, 0, "Send complete callback not called");
1015 k_msgq_cleanup(&frame_msgq);
1016 can_remove_rx_filter(can_dev, filter_id);
1017 }
1018
ZTEST(isotp_conformance,test_canfd_mandatory_padding)1019 ZTEST(isotp_conformance, test_canfd_mandatory_padding)
1020 {
1021 /* Mandatory padding of CAN FD frames (TX_DL > 8).
1022 * Must be padded with 0xCC up to the nearest DLC.
1023 */
1024 #if TX_DL < 12
1025 ztest_test_skip();
1026 #else
1027 /* Input a single frame packet of 10 bytes */
1028 uint8_t data_size_sf = 10 - 2;
1029 int filter_id, ret;
1030 struct can_frame frame = {};
1031 const uint8_t expected_padding[] = { 0xCC, 0xCC };
1032
1033 filter_id = add_rx_msgq(rx_addr.std_id, CAN_STD_ID_MASK);
1034
1035 ret = isotp_send(&send_ctx, can_dev, random_data, data_size_sf,
1036 &rx_addr, &tx_addr, send_complete_cb, INT_TO_POINTER(ISOTP_N_OK));
1037 zassert_equal(ret, 0, "Send returned %d", ret);
1038
1039 ret = k_msgq_get(&frame_msgq, &frame, K_MSEC(500));
1040 zassert_equal(ret, 0, "Timeout waiting for msg. ret: %d", ret);
1041
1042 /* The output frame should be 12 bytes, with the last two bytes being 0xCC */
1043 zassert_equal(can_dlc_to_bytes(frame.dlc), 12, "Incorrect DLC");
1044 zassert_mem_equal(&frame.data[10], expected_padding, sizeof(expected_padding));
1045
1046 can_remove_rx_filter(can_dev, filter_id);
1047 #endif
1048 }
1049
ZTEST(isotp_conformance,test_canfd_rx_dl_validation)1050 ZTEST(isotp_conformance, test_canfd_rx_dl_validation)
1051 {
1052 /* First frame defines the RX data length, consecutive frames
1053 * must have the same length (except the last frame)
1054 */
1055 #if TX_DL < 16
1056 ztest_test_skip();
1057 #else
1058
1059 uint8_t data_size_ff = 16 - 2;
1060 uint8_t data_size_cf = 12 - 1;
1061 uint8_t data_send_length = data_size_ff + 2 * data_size_cf;
1062 const uint8_t *data_ptr = random_data;
1063 int filter_id, ret;
1064 struct frame_desired fc_frame, ff_frame;
1065
1066 /* FF uses a TX_DL of 16 */
1067 ff_frame.data[0] = FF_PCI_BYTE_1(data_send_length);
1068 ff_frame.data[1] = FF_PCI_BYTE_2(data_send_length);
1069 memcpy(&ff_frame.data[2], data_ptr, data_size_ff);
1070 ff_frame.length = data_size_ff + 2;
1071 data_ptr += data_size_ff;
1072
1073 prepare_fc_frame(&fc_frame, FC_PCI_CTS, &fc_opts_single, true);
1074
1075 /* Two CF frames using a TX_DL of 12 */
1076 des_frames[0].data[0] = CF_PCI_BYTE_1 | (1 & 0x0F);
1077 des_frames[0].length = data_size_cf + 1;
1078 memcpy(&des_frames[0].data[1], data_ptr, data_size_cf);
1079 data_ptr += data_size_cf;
1080
1081 des_frames[1].data[0] = CF_PCI_BYTE_1 | (2 & 0x0F);
1082 des_frames[1].length = data_size_cf + 1;
1083 memcpy(&des_frames[1].data[1], data_ptr, data_size_cf);
1084 data_ptr += data_size_cf;
1085
1086 filter_id = add_rx_msgq(tx_addr.std_id, CAN_STD_ID_MASK);
1087
1088 ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
1089 &fc_opts_single, K_NO_WAIT);
1090 zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret);
1091
1092 send_frame_series(&ff_frame, 1, rx_addr.std_id);
1093
1094 check_frame_series(&fc_frame, 1, &frame_msgq);
1095
1096 send_frame_series(des_frames, 2, rx_addr.std_id);
1097
1098 /* Assert that the packet was dropped and an error returned */
1099 ret = isotp_recv(&recv_ctx, data_buf, sizeof(data_buf), K_MSEC(200));
1100 zassert_equal(ret, ISOTP_N_ERROR, "recv returned %d", ret);
1101
1102 can_remove_rx_filter(can_dev, filter_id);
1103 isotp_unbind(&recv_ctx);
1104 #endif
1105 }
1106
canfd_predicate(const void * state)1107 static bool canfd_predicate(const void *state)
1108 {
1109 ARG_UNUSED(state);
1110
1111 #ifdef CONFIG_TEST_USE_CAN_FD_MODE
1112 can_mode_t cap;
1113 int err;
1114
1115 err = can_get_capabilities(can_dev, &cap);
1116 zassert_equal(err, 0, "failed to get CAN controller capabilities (err %d)", err);
1117
1118 if ((cap & CAN_MODE_FD) == 0) {
1119 return false;
1120 }
1121 #endif
1122
1123 return true;
1124 }
1125
isotp_conformance_setup(void)1126 static void *isotp_conformance_setup(void)
1127 {
1128 int ret;
1129
1130 zassert_true(sizeof(random_data) >= sizeof(data_buf) * 2 + 10,
1131 "Test data size to small");
1132
1133 zassert_true(device_is_ready(can_dev), "CAN device not ready");
1134
1135 (void)can_stop(can_dev);
1136
1137 ret = can_set_mode(can_dev, CAN_MODE_LOOPBACK |
1138 (IS_ENABLED(CONFIG_TEST_USE_CAN_FD_MODE) ? CAN_MODE_FD : 0));
1139 zassert_equal(ret, 0, "Failed to set mode [%d]", ret);
1140
1141 ret = can_start(can_dev);
1142 zassert_equal(ret, 0, "Failed to start CAN controller [%d]", ret);
1143
1144 k_sem_init(&send_compl_sem, 0, 1);
1145
1146 return NULL;
1147 }
1148
1149 ZTEST_SUITE(isotp_conformance, canfd_predicate, isotp_conformance_setup, NULL, NULL, NULL);
1150