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