tests: subsys: can: Add tests for iso tp

This commit adds testing for CAN ISO-TP

Signed-off-by: Alexander Wachter <alexander.wachter@student.tugraz.at>
This commit is contained in:
Alexander Wachter 2019-02-20 11:47:30 +01:00 committed by Jukka Rissanen
commit 3650f21bd8
14 changed files with 1576 additions and 0 deletions

View file

@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.13.1)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(integration)
FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})

View file

@ -0,0 +1,8 @@
CONFIG_CAN=y
CONFIG_ZTEST=y
CONFIG_ISOTP=y
CONFIG_ISOTP_USE_TX_BUF=y
CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS=y
CONFIG_ISOTP_RX_BUF_COUNT=6
CONFIG_ISOTP_RX_BUF_SIZE=128
CONFIG_ISOTP_RX_SF_FF_BUF_COUNT=2

View file

@ -0,0 +1,906 @@
/*
* Copyright (c) 2019 Alexander Wachter
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <canbus/isotp.h>
#include <drivers/can.h>
#include <ztest.h>
#include <strings.h>
#include "random_data.h"
#define PCI_TYPE_POS 4
#define DATA_SIZE_SF 7
#define DATA_SIZE_CF 7
#define DATA_SIZE_SF_EXT 6
#define DATA_SIZE_FF 6
#define CAN_DL 8
#define DATA_SEND_LENGTH 272
#define SF_PCI_TYPE 0
#define SF_PCI_BYTE_1 ((SF_PCI_TYPE << PCI_TYPE_POS) | DATA_SIZE_SF)
#define SF_PCI_BYTE_2_EXT ((SF_PCI_TYPE << PCI_TYPE_POS) | DATA_SIZE_SF_EXT)
#define SF_PCI_BYTE_LEN_8 ((SF_PCI_TYPE << PCI_TYPE_POS) | (DATA_SIZE_SF + 1))
#define EXT_ADDR 5
#define FF_PCI_TYPE 1
#define FF_PCI_BYTE_1(dl) ((FF_PCI_TYPE << PCI_TYPE_POS) | ((dl) >> 8))
#define FF_PCI_BYTE_2(dl) ((dl) & 0xFF)
#define FC_PCI_TYPE 3
#define FC_PCI_CTS 0
#define FC_PCI_WAIT 1
#define FC_PCI_OVFLW 2
#define FC_PCI_BYTE_1(FS) ((FC_PCI_TYPE << PCI_TYPE_POS) | (FS))
#define FC_PCI_BYTE_2(BS) (BS)
#define FC_PCI_BYTE_3(ST_MIN) (ST_MIN)
#define DATA_SIZE_FC 3
#define CF_PCI_TYPE 2
#define CF_PCI_BYTE_1 (CF_PCI_TYPE << PCI_TYPE_POS)
#define STMIN_VAL_1 5
#define STMIN_VAL_2 50
#define STMIN_UPPER_TOLERANCE 5
#define CEIL(A, B) (((A) + (B) - 1) / (B))
#define BS_TIMEOUT_UPPER_MS 1100
#define BS_TIMEOUT_LOWER_MS 1000
#if defined(CONFIG_CAN_LOOPBACK_DEV_NAME)
#define CAN_DEVICE_NAME CONFIG_CAN_LOOPBACK_DEV_NAME
#else
#define CAN_DEVICE_NAME DT_ALIAS_CAN_PRIMARY_LABEL
#endif
/*
* @addtogroup t_can
* @{
* @defgroup t_can_isotp test_can_isotp
* @brief TestPurpose: verify correctness of the iso tp implementation
* @details
* - Test Steps
* -#
* - Expected Results
* -#
* @}
*/
struct frame_desired {
u8_t data[8];
u8_t length;
};
struct frame_desired des_frames[CEIL((DATA_SEND_LENGTH - DATA_SIZE_FF),
DATA_SIZE_CF)];
const struct isotp_fc_opts fc_opts = {
.bs = 8,
.stmin = 0
};
const struct isotp_fc_opts fc_opts_single = {
.bs = 0,
.stmin = 0
};
const struct isotp_msg_id rx_addr = {
.std_id = 0x10,
.id_type = CAN_STANDARD_IDENTIFIER,
.use_ext_addr = 0
};
const struct isotp_msg_id tx_addr = {
.std_id = 0x11,
.id_type = CAN_STANDARD_IDENTIFIER,
.use_ext_addr = 0
};
const struct isotp_msg_id rx_addr_ext = {
.std_id = 0x10,
.id_type = CAN_STANDARD_IDENTIFIER,
.use_ext_addr = 1,
.ext_addr = EXT_ADDR
};
const struct isotp_msg_id tx_addr_ext = {
.std_id = 0x11,
.id_type = CAN_STANDARD_IDENTIFIER,
.use_ext_addr = 1,
.ext_addr = EXT_ADDR
};
struct device *can_dev;
struct isotp_recv_ctx recv_ctx;
struct isotp_send_ctx send_ctx;
u8_t data_buf[128];
CAN_DEFINE_MSGQ(frame_msgq, 10);
struct k_sem send_compl_sem;
void send_complette_cb(int error_nr, void *arg)
{
int expected_err_nr = (int) arg;
zassert_equal(error_nr, expected_err_nr,
"Unexpected error nr. expect: %d, got %d",
expected_err_nr, error_nr);
k_sem_give(&send_compl_sem);
}
static void print_hex(const u8_t *ptr, size_t len)
{
while (len--) {
printk("%02x ", *ptr++);
}
}
static int check_data(const u8_t *frame, const u8_t *desired, size_t length)
{
int ret;
ret = memcmp(frame, desired, length);
if (ret) {
printk("desired bytes:\n");
print_hex(desired, length);
printk("\nreceived (%d bytes):\n", length);
print_hex(frame, length);
printk("\n");
}
return ret;
}
static void send_sf(void)
{
int ret;
ret = isotp_send(&send_ctx, can_dev, random_data, DATA_SIZE_SF,
&rx_addr, &tx_addr, send_complette_cb, ISOTP_N_OK);
zassert_equal(ret, 0, "Send returned %d", ret);
}
static void get_sf(struct isotp_recv_ctx *recv_ctx, size_t data_size)
{
int ret;
memset(data_buf, 0, sizeof(data_buf));
ret = isotp_recv(recv_ctx, data_buf, sizeof(data_buf), K_MSEC(1000));
zassert_equal(ret, data_size, "recv returned %d", ret);
ret = check_data(data_buf, random_data, data_size);
zassert_equal(ret, 0, "Data differ");
}
static void get_sf_ignore(struct isotp_recv_ctx *recv_ctx)
{
int ret;
ret = isotp_recv(recv_ctx, data_buf, sizeof(data_buf), K_MSEC(200));
zassert_equal(ret, ISOTP_RECV_TIMEOUT, "recv returned %d", ret);
}
static void send_test_data(const u8_t *data, size_t len)
{
int ret;
ret = isotp_send(&send_ctx, can_dev, data, len, &rx_addr, &tx_addr,
send_complette_cb, ISOTP_N_OK);
zassert_equal(ret, 0, "Send returned %d", ret);
}
static void receive_test_data(struct isotp_recv_ctx *recv_ctx,
const u8_t *data, size_t len, s32_t delay)
{
size_t remaining_len = len;
int ret, recv_len;
const u8_t *data_ptr = data;
do {
memset(data_buf, 0, sizeof(data_buf));
recv_len = isotp_recv(recv_ctx, data_buf, sizeof(data_buf),
K_MSEC(1000));
zassert_true(recv_len >= 0, "recv error: %d", recv_len);
zassert_true(remaining_len >= recv_len,
"More data then expected");
ret = check_data(data_buf, data_ptr, recv_len);
zassert_equal(ret, 0, "Data differ");
data_ptr += recv_len;
remaining_len -= recv_len;
if (delay) {
k_sleep(delay);
}
} while (remaining_len);
ret = isotp_recv(recv_ctx, data_buf, sizeof(data_buf), K_MSEC(50));
zassert_equal(ret, ISOTP_RECV_TIMEOUT,
"Expected timeout but got %d", ret);
}
static void send_frame_series(struct frame_desired *frames, size_t length,
u32_t id)
{
int i, ret;
struct zcan_frame frame = {
.id_type = CAN_STANDARD_IDENTIFIER,
.rtr = CAN_DATAFRAME,
.std_id = id
};
struct frame_desired *desired = frames;
for (i = 0; i < length; i++) {
frame.dlc = desired->length;
memcpy(frame.data, desired->data, desired->length);
ret = can_send(can_dev, &frame, K_MSEC(500), NULL, NULL);
zassert_equal(ret, CAN_TX_OK, "Sending msg %d failed.", i);
desired++;
}
}
static void check_frame_series(struct frame_desired *frames, size_t length,
struct k_msgq *msgq)
{
int i, ret;
struct zcan_frame frame;
struct frame_desired *desired = frames;
for (i = 0; i < length; i++) {
ret = k_msgq_get(msgq, &frame, K_MSEC(500));
zassert_equal(ret, 0, "Timeout waiting for msg nr %d. ret: %d",
i, ret);
zassert_equal(frame.dlc, desired->length,
"DLC of frame nr %d differ. Desired: %d, Got: %d",
i, desired->length, frame.dlc);
ret = check_data(frame.data, desired->data, desired->length);
zassert_equal(ret, 0, "Data differ");
desired++;
}
ret = k_msgq_get(msgq, &frame, K_MSEC(200));
zassert_equal(ret, -EAGAIN, "Expected timeout, but received %d", ret);
}
static int attach_msgq(u32_t id)
{
int filter_id;
struct zcan_filter filter = {
.id_type = CAN_STANDARD_IDENTIFIER,
.rtr = CAN_DATAFRAME,
.std_id = id,
.rtr_mask = 1,
.std_id_mask = CAN_STD_ID_MASK
};
filter_id = can_attach_msgq(can_dev, &frame_msgq, &filter);
zassert_not_equal(filter_id, CAN_NO_FREE_FILTER, "Filter full");
zassert_true((filter_id >= 0), "Negative filter number [%d]",
filter_id);
return filter_id;
}
static void prepare_cf_frames(struct frame_desired *frames, size_t frames_cnt,
const u8_t *data, size_t data_len)
{
int i;
const u8_t *data_ptr = data;
size_t remaining_length = data_len;
for (i = 0; i < frames_cnt && remaining_length; i++) {
frames[i].data[0] = CF_PCI_BYTE_1 | ((i+1) & 0x0F);
frames[i].length = CAN_DL;
memcpy(&des_frames[i].data[1], data_ptr, DATA_SIZE_CF);
if (remaining_length < DATA_SIZE_CF) {
frames[i].length = remaining_length + 1;
remaining_length = 0;
}
remaining_length -= DATA_SIZE_CF;
data_ptr += DATA_SIZE_CF;
}
}
static void test_send_sf(void)
{
int filter_id;
struct frame_desired des_frame;
des_frame.data[0] = SF_PCI_BYTE_1;
memcpy(&des_frame.data[1], random_data, DATA_SIZE_SF);
des_frame.length = DATA_SIZE_SF + 1;
filter_id = attach_msgq(rx_addr.std_id);
zassert_true((filter_id >= 0), "Negative filter number [%d]",
filter_id);
send_sf();
check_frame_series(&des_frame, 1, &frame_msgq);
can_detach(can_dev, filter_id);
}
static void test_receive_sf(void)
{
int ret;
struct frame_desired single_frame;
single_frame.data[0] = SF_PCI_BYTE_1;
memcpy(&single_frame.data[1], random_data, DATA_SIZE_SF);
single_frame.length = DATA_SIZE_SF + 1;
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
&fc_opts_single, K_NO_WAIT);
zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret);
send_frame_series(&single_frame, 1, rx_addr.std_id);
get_sf(&recv_ctx, DATA_SIZE_SF);
single_frame.data[0] = SF_PCI_BYTE_LEN_8;
send_frame_series(&single_frame, 1, rx_addr.std_id);
single_frame.data[0] = SF_PCI_BYTE_1;
single_frame.length = 7;
send_frame_series(&single_frame, 1, rx_addr.std_id);
get_sf_ignore(&recv_ctx);
isotp_unbind(&recv_ctx);
}
static void test_send_sf_ext(void)
{
int filter_id, ret;
struct frame_desired des_frame;
des_frame.data[0] = rx_addr_ext.ext_addr;
des_frame.data[1] = SF_PCI_BYTE_2_EXT;
memcpy(&des_frame.data[2], random_data, DATA_SIZE_SF_EXT);
des_frame.length = DATA_SIZE_SF_EXT + 2;
filter_id = attach_msgq(rx_addr_ext.std_id);
zassert_true((filter_id >= 0), "Negative filter number [%d]",
filter_id);
ret = isotp_send(&send_ctx, can_dev, random_data, DATA_SIZE_SF_EXT,
&rx_addr_ext, &tx_addr_ext, send_complette_cb,
ISOTP_N_OK);
zassert_equal(ret, 0, "Send returned %d", ret);
check_frame_series(&des_frame, 1, &frame_msgq);
can_detach(can_dev, filter_id);
}
static void test_receive_sf_ext(void)
{
int ret;
struct frame_desired single_frame;
single_frame.data[0] = EXT_ADDR;
single_frame.data[1] = SF_PCI_BYTE_2_EXT;
memcpy(&single_frame.data[2], random_data, DATA_SIZE_SF_EXT);
single_frame.length = DATA_SIZE_SF_EXT + 2;
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr_ext, &tx_addr,
&fc_opts_single, K_NO_WAIT);
zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret);
send_frame_series(&single_frame, 1, rx_addr.std_id);
get_sf(&recv_ctx, DATA_SIZE_SF_EXT);
single_frame.data[1] = SF_PCI_BYTE_1;
send_frame_series(&single_frame, 1, rx_addr.std_id);
single_frame.data[1] = SF_PCI_BYTE_2_EXT;
single_frame.length = 7;
send_frame_series(&single_frame, 1, rx_addr.std_id);
get_sf_ignore(&recv_ctx);
isotp_unbind(&recv_ctx);
}
static void test_send_data(void)
{
struct frame_desired fc_frame, ff_frame;
const u8_t *data_ptr = random_data;
size_t remaining_length = DATA_SEND_LENGTH;
int filter_id;
ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SEND_LENGTH);
ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SEND_LENGTH);
memcpy(&ff_frame.data[2], data_ptr, DATA_SIZE_FF);
ff_frame.length = CAN_DL;
data_ptr += DATA_SIZE_FF;
remaining_length -= DATA_SIZE_FF;
fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_CTS);
fc_frame.data[1] = FC_PCI_BYTE_2(0);
fc_frame.data[2] = FC_PCI_BYTE_3(0);
fc_frame.length = 3;
prepare_cf_frames(des_frames, ARRAY_SIZE(des_frames), data_ptr,
remaining_length);
filter_id = attach_msgq(rx_addr.std_id);
zassert_true((filter_id >= 0), "Negative filter number [%d]",
filter_id);
send_test_data(random_data, DATA_SEND_LENGTH);
check_frame_series(&ff_frame, 1, &frame_msgq);
send_frame_series(&fc_frame, 1, tx_addr.std_id);
check_frame_series(des_frames, ARRAY_SIZE(des_frames), &frame_msgq);
can_detach(can_dev, filter_id);
}
static void test_send_data_blocks(void)
{
const u8_t *data_ptr = random_data;
size_t remaining_length = DATA_SEND_LENGTH;
struct frame_desired *data_frame_ptr = des_frames;
int filter_id, ret;
struct zcan_frame dummy_frame;
struct frame_desired fc_frame, ff_frame;
ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SEND_LENGTH);
ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SEND_LENGTH);
memcpy(&ff_frame.data[2], data_ptr, DATA_SIZE_FF);
ff_frame.length = DATA_SIZE_FF + 2;
data_ptr += DATA_SIZE_FF;
remaining_length -= DATA_SIZE_FF;
fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_CTS);
fc_frame.data[1] = FC_PCI_BYTE_2(fc_opts.bs);
fc_frame.data[2] = FC_PCI_BYTE_3(0);
fc_frame.length = 3;
prepare_cf_frames(des_frames, ARRAY_SIZE(des_frames), data_ptr,
remaining_length);
remaining_length = DATA_SEND_LENGTH;
filter_id = attach_msgq(rx_addr.std_id);
zassert_true((filter_id >= 0), "Negative filter number [%d]",
filter_id);
send_test_data(random_data, DATA_SEND_LENGTH);
check_frame_series(&ff_frame, 1, &frame_msgq);
remaining_length -= DATA_SIZE_FF;
send_frame_series(&fc_frame, 1, tx_addr.std_id);
check_frame_series(data_frame_ptr, fc_opts.bs, &frame_msgq);
data_frame_ptr += fc_opts.bs;
remaining_length -= fc_opts.bs * DATA_SIZE_CF;
ret = k_msgq_get(&frame_msgq, &dummy_frame, K_MSEC(50));
zassert_equal(ret, -EAGAIN, "Expected timeout but got %d", ret);
fc_frame.data[1] = FC_PCI_BYTE_2(2);
send_frame_series(&fc_frame, 1, tx_addr.std_id);
/* dynamic bs */
check_frame_series(data_frame_ptr, 2, &frame_msgq);
data_frame_ptr += 2;
remaining_length -= 2 * DATA_SIZE_CF;
ret = k_msgq_get(&frame_msgq, &dummy_frame, K_MSEC(50));
zassert_equal(ret, -EAGAIN, "Expected timeout but got %d", ret);
/* get the rest */
fc_frame.data[1] = FC_PCI_BYTE_2(0);
send_frame_series(&fc_frame, 1, tx_addr.std_id);
check_frame_series(data_frame_ptr, CEIL(remaining_length, DATA_SIZE_CF),
&frame_msgq);
ret = k_msgq_get(&frame_msgq, &dummy_frame, K_MSEC(50));
zassert_equal(ret, -EAGAIN, "Expected timeout but got %d", ret);
can_detach(can_dev, filter_id);
}
static void test_receive_data(void)
{
const u8_t *data_ptr = random_data;
size_t remaining_length = DATA_SEND_LENGTH;
int filter_id, ret;
struct frame_desired fc_frame, ff_frame;
ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SEND_LENGTH);
ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SEND_LENGTH);
memcpy(&ff_frame.data[2], data_ptr, DATA_SIZE_FF);
ff_frame.length = CAN_DL;
data_ptr += DATA_SIZE_FF;
remaining_length -= DATA_SIZE_FF;
fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_CTS);
fc_frame.data[1] = FC_PCI_BYTE_2(fc_opts_single.bs);
fc_frame.data[2] = FC_PCI_BYTE_3(fc_opts_single.stmin);
fc_frame.length = 3;
prepare_cf_frames(des_frames, ARRAY_SIZE(des_frames), data_ptr,
remaining_length);
filter_id = attach_msgq(tx_addr.std_id);
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
&fc_opts_single, K_NO_WAIT);
zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret);
send_frame_series(&ff_frame, 1, rx_addr.std_id);
check_frame_series(&fc_frame, 1, &frame_msgq);
send_frame_series(des_frames, ARRAY_SIZE(des_frames), rx_addr.std_id);
receive_test_data(&recv_ctx, random_data, DATA_SEND_LENGTH, 0);
can_detach(can_dev, filter_id);
isotp_unbind(&recv_ctx);
}
static void test_receive_data_blocks(void)
{
const u8_t *data_ptr = random_data;
size_t remaining_length = DATA_SEND_LENGTH;
struct frame_desired *data_frame_ptr = des_frames;
int filter_id, ret;
size_t remaining_frames;
struct frame_desired fc_frame, ff_frame;
struct zcan_frame dummy_frame;
ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SEND_LENGTH);
ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SEND_LENGTH);
memcpy(&ff_frame.data[2], data_ptr, DATA_SIZE_FF);
ff_frame.length = DATA_SIZE_FF + 2;
data_ptr += DATA_SIZE_FF;
remaining_length -= DATA_SIZE_FF;
fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_CTS);
fc_frame.data[1] = FC_PCI_BYTE_2(fc_opts.bs);
fc_frame.data[2] = FC_PCI_BYTE_3(fc_opts.stmin);
fc_frame.length = 3;
prepare_cf_frames(des_frames, ARRAY_SIZE(des_frames), data_ptr,
remaining_length);
remaining_frames = CEIL(remaining_length, DATA_SIZE_CF);
filter_id = attach_msgq(tx_addr.std_id);
zassert_true((filter_id >= 0), "Negative filter number [%d]",
filter_id);
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
&fc_opts, K_NO_WAIT);
zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret);
send_frame_series(&ff_frame, 1, rx_addr.std_id);
while (remaining_frames) {
check_frame_series(&fc_frame, 1, &frame_msgq);
if (remaining_frames >= fc_opts.bs) {
send_frame_series(data_frame_ptr, fc_opts.bs,
rx_addr.std_id);
data_frame_ptr += fc_opts.bs;
remaining_frames -= fc_opts.bs;
} else {
send_frame_series(data_frame_ptr, remaining_frames,
rx_addr.std_id);
data_frame_ptr += remaining_frames;
remaining_frames = 0;
}
}
ret = k_msgq_get(&frame_msgq, &dummy_frame, K_MSEC(50));
zassert_equal(ret, -EAGAIN, "Expected timeout but got %d", ret);
receive_test_data(&recv_ctx, random_data, DATA_SEND_LENGTH, 0);
can_detach(can_dev, filter_id);
isotp_unbind(&recv_ctx);
}
static void test_send_timeouts(void)
{
int ret;
u32_t start_time, time_diff;
struct frame_desired fc_cts_frame;
fc_cts_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_CTS);
fc_cts_frame.data[1] = FC_PCI_BYTE_2(fc_opts.bs);
fc_cts_frame.data[2] = FC_PCI_BYTE_3(0);
fc_cts_frame.length = 3;
/* Test timeout for first FC*/
start_time = k_uptime_get_32();
ret = isotp_send(&send_ctx, can_dev, random_data, sizeof(random_data),
&tx_addr, &rx_addr, NULL, NULL);
time_diff = k_uptime_get_32() - start_time;
zassert_equal(ret, ISOTP_N_TIMEOUT_BS, "Expected timeout but got %d",
ret);
zassert_true(time_diff <= BS_TIMEOUT_UPPER_MS,
"Timeout too late (%dms)", time_diff);
zassert_true(time_diff >= BS_TIMEOUT_LOWER_MS,
"Timeout too early (%dms)", time_diff);
/* Test timeout for consecutive FC frames */
k_sem_reset(&send_compl_sem);
ret = isotp_send(&send_ctx, can_dev, random_data, sizeof(random_data),
&tx_addr, &rx_addr, send_complette_cb,
(void *)ISOTP_N_TIMEOUT_BS);
send_frame_series(&fc_cts_frame, 1, rx_addr.std_id);
start_time = k_uptime_get_32();
ret = k_sem_take(&send_compl_sem, K_MSEC(BS_TIMEOUT_UPPER_MS));
zassert_equal(ret, 0, "Timeout too late");
time_diff = k_uptime_get_32() - start_time;
zassert_true(time_diff >= BS_TIMEOUT_LOWER_MS,
"Timeout too early (%dms)", time_diff);
/* Test timeout reset with WAIT frame */
k_sem_reset(&send_compl_sem);
ret = isotp_send(&send_ctx, can_dev, random_data, sizeof(random_data),
&tx_addr, &rx_addr, send_complette_cb,
(void *)ISOTP_N_TIMEOUT_BS);
ret = k_sem_take(&send_compl_sem, K_MSEC(800));
zassert_equal(ret, -EAGAIN, "Timeout too early");
fc_cts_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_CTS);
send_frame_series(&fc_cts_frame, 1, rx_addr.std_id);
start_time = k_uptime_get_32();
ret = k_sem_take(&send_compl_sem, K_MSEC(BS_TIMEOUT_UPPER_MS));
zassert_equal(ret, 0, "Timeout too late");
time_diff = k_uptime_get_32() - start_time;
zassert_true(time_diff >= BS_TIMEOUT_LOWER_MS,
"Timeout too early (%dms)", time_diff);
}
static void test_receive_timeouts(void)
{
int ret;
u32_t start_time, time_diff;
struct frame_desired ff_frame;
ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SEND_LENGTH);
ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SEND_LENGTH);
memcpy(&ff_frame.data[2], random_data, DATA_SIZE_FF);
ff_frame.length = DATA_SIZE_FF + 2;
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
&fc_opts, K_NO_WAIT);
zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret);
send_frame_series(&ff_frame, 1, rx_addr.std_id);
start_time = k_uptime_get_32();
ret = isotp_recv(&recv_ctx, data_buf, sizeof(data_buf), K_FOREVER);
zassert_equal(ret, DATA_SIZE_FF,
"Expected FF data length but got %d", ret);
ret = isotp_recv(&recv_ctx, data_buf, sizeof(data_buf), K_FOREVER);
zassert_equal(ret, ISOTP_N_TIMEOUT_CR,
"Expected timeout but got %d", ret);
time_diff = k_uptime_get_32() - start_time;
zassert_true(time_diff >= BS_TIMEOUT_LOWER_MS,
"Timeout too early (%dms)", time_diff);
zassert_true(time_diff <= BS_TIMEOUT_UPPER_MS,
"Timeout too slow (%dms)", time_diff);
isotp_unbind(&recv_ctx);
}
static void test_stmin(void)
{
int filter_id, ret;
struct frame_desired fc_frame, ff_frame;
struct zcan_frame raw_frame;
u32_t start_time, time_diff;
ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SIZE_FF + DATA_SIZE_CF * 4);
ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SIZE_FF + DATA_SIZE_CF * 4);
memcpy(&ff_frame.data[2], random_data, DATA_SIZE_FF);
ff_frame.length = DATA_SIZE_FF + 2;
fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_CTS);
fc_frame.data[1] = FC_PCI_BYTE_2(2);
fc_frame.data[2] = FC_PCI_BYTE_3(STMIN_VAL_1);
fc_frame.length = 3;
filter_id = attach_msgq(rx_addr.std_id);
zassert_true((filter_id >= 0), "Negative filter number [%d]",
filter_id);
send_test_data(random_data, DATA_SIZE_FF + DATA_SIZE_CF * 4);
check_frame_series(&ff_frame, 1, &frame_msgq);
send_frame_series(&fc_frame, 1, tx_addr.std_id);
ret = k_msgq_get(&frame_msgq, &raw_frame, K_MSEC(100));
zassert_equal(ret, 0, "Expected to get a message. [%d]", ret);
start_time = k_uptime_get_32();
ret = k_msgq_get(&frame_msgq, &raw_frame,
K_MSEC(STMIN_VAL_1 + STMIN_UPPER_TOLERANCE));
time_diff = k_uptime_get_32() - start_time;
zassert_equal(ret, 0, "Expected to get a message within %dms. [%d]",
STMIN_VAL_1 + STMIN_UPPER_TOLERANCE, ret);
zassert_true(time_diff >= STMIN_VAL_1, "STmin too short (%dms)",
time_diff);
fc_frame.data[2] = FC_PCI_BYTE_3(STMIN_VAL_2);
send_frame_series(&fc_frame, 1, tx_addr.std_id);
ret = k_msgq_get(&frame_msgq, &raw_frame, K_MSEC(100));
zassert_equal(ret, 0, "Expected to get a message. [%d]", ret);
start_time = k_uptime_get_32();
ret = k_msgq_get(&frame_msgq, &raw_frame,
K_MSEC(STMIN_VAL_2 + STMIN_UPPER_TOLERANCE));
time_diff = k_uptime_get_32() - start_time;
zassert_equal(ret, 0, "Expected to get a message within %dms. [%d]",
STMIN_VAL_2 + STMIN_UPPER_TOLERANCE, ret);
zassert_true(time_diff >= STMIN_VAL_2, "STmin too short (%dms)",
time_diff);
can_detach(can_dev, filter_id);
}
void test_receiver_fc_errors(void)
{
int ret, filter_id;
struct frame_desired ff_frame, fc_frame;
ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SEND_LENGTH);
ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SEND_LENGTH);
memcpy(&ff_frame.data[2], random_data, DATA_SIZE_FF);
ff_frame.length = DATA_SIZE_FF + 2;
fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_CTS);
fc_frame.data[1] = FC_PCI_BYTE_2(fc_opts.bs);
fc_frame.data[2] = FC_PCI_BYTE_3(fc_opts.stmin);
fc_frame.length = 3;
filter_id = attach_msgq(tx_addr.std_id);
zassert_true((filter_id >= 0), "Negative filter number [%d]",
filter_id);
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
&fc_opts, K_NO_WAIT);
zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret);
/* wrong sequence number */
send_frame_series(&ff_frame, 1, rx_addr.std_id);
check_frame_series(&fc_frame, 1, &frame_msgq);
prepare_cf_frames(des_frames, ARRAY_SIZE(des_frames),
random_data + DATA_SIZE_FF,
sizeof(random_data) - DATA_SIZE_FF);
/* SN should be 2 but is set to 3 for this test */
des_frames[1].data[0] = CF_PCI_BYTE_1 | (3 & 0x0F);
send_frame_series(des_frames, fc_opts.bs, rx_addr.std_id);
ret = isotp_recv(&recv_ctx, data_buf, sizeof(data_buf), K_MSEC(200));
zassert_equal(ret, DATA_SIZE_FF,
"Expected FF data length but got %d", ret);
ret = isotp_recv(&recv_ctx, data_buf, sizeof(data_buf), K_MSEC(200));
zassert_equal(ret, ISOTP_N_WRONG_SN,
"Expected wrong SN but got %d", ret);
can_detach(can_dev, filter_id);
k_msgq_cleanup(&frame_msgq);
isotp_unbind(&recv_ctx);
}
void test_sender_fc_errors(void)
{
int ret, filter_id, i;
struct frame_desired ff_frame, fc_frame;
ff_frame.data[0] = FF_PCI_BYTE_1(DATA_SEND_LENGTH);
ff_frame.data[1] = FF_PCI_BYTE_2(DATA_SEND_LENGTH);
memcpy(&ff_frame.data[2], random_data, DATA_SIZE_FF);
ff_frame.length = DATA_SIZE_FF + 2;
filter_id = attach_msgq(tx_addr.std_id);
/* invalid flow status */
fc_frame.data[0] = FC_PCI_BYTE_1(3);
fc_frame.data[1] = FC_PCI_BYTE_2(fc_opts.bs);
fc_frame.data[2] = FC_PCI_BYTE_3(fc_opts.stmin);
fc_frame.length = 3;
k_sem_reset(&send_compl_sem);
ret = isotp_send(&send_ctx, can_dev, random_data, DATA_SEND_LENGTH,
&tx_addr, &rx_addr, send_complette_cb,
(void *)ISOTP_N_INVALID_FS);
check_frame_series(&ff_frame, 1, &frame_msgq);
send_frame_series(&fc_frame, 1, rx_addr.std_id);
ret = k_sem_take(&send_compl_sem, K_MSEC(200));
zassert_equal(ret, 0, "Send complete callback not called");
/* buffer overflow */
can_detach(can_dev, filter_id);
ret = isotp_bind(&recv_ctx, can_dev, &tx_addr, &rx_addr,
&fc_opts_single, K_NO_WAIT);
zassert_equal(ret, ISOTP_N_OK, "Binding failed [%d]", ret);
ret = isotp_send(&send_ctx, can_dev, random_data, 5*1024,
&tx_addr, &rx_addr, NULL, NULL);
zassert_equal(ret, ISOTP_N_BUFFER_OVERFLW,
"Expected overflow bot got %d", ret);
isotp_unbind(&recv_ctx);
filter_id = attach_msgq(tx_addr.std_id);
k_sem_reset(&send_compl_sem);
ret = isotp_send(&send_ctx, can_dev, random_data, DATA_SEND_LENGTH,
&tx_addr, &rx_addr, send_complette_cb,
(void *)ISOTP_N_BUFFER_OVERFLW);
check_frame_series(&ff_frame, 1, &frame_msgq);
fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_OVFLW);
send_frame_series(&fc_frame, 1, rx_addr.std_id);
ret = k_sem_take(&send_compl_sem, K_MSEC(200));
zassert_equal(ret, 0, "Send complete callback not called");
/* wft overrun */
k_sem_reset(&send_compl_sem);
ret = isotp_send(&send_ctx, can_dev, random_data, DATA_SEND_LENGTH,
&tx_addr, &rx_addr, send_complette_cb,
(void *)ISOTP_N_WFT_OVRN);
check_frame_series(&ff_frame, 1, &frame_msgq);
fc_frame.data[0] = FC_PCI_BYTE_1(FC_PCI_WAIT);
for (i = 0; i < CONFIG_ISOTP_WFTMAX + 1; i++) {
send_frame_series(&fc_frame, 1, rx_addr.std_id);
}
ret = k_sem_take(&send_compl_sem, K_MSEC(200));
zassert_equal(ret, 0, "Send complete callback not called");
k_msgq_cleanup(&frame_msgq);
can_detach(can_dev, filter_id);
}
void test_main(void)
{
int ret;
zassert_true(sizeof(random_data) >= sizeof(data_buf) * 2 + 10,
"Test data size to small");
can_dev = device_get_binding(CAN_DEVICE_NAME);
zassert_not_null(can_dev, "CAN device not not found");
ret = can_configure(can_dev, CAN_LOOPBACK_MODE, 0);
zassert_equal(ret, 0, "Failed to set loopback mode [%d]", ret);
k_sem_init(&send_compl_sem, 0, 1);
ztest_test_suite(isotp_conformance,
ztest_unit_test(test_send_sf),
ztest_unit_test(test_receive_sf),
ztest_unit_test(test_send_sf_ext),
ztest_unit_test(test_receive_sf_ext),
ztest_unit_test(test_send_data),
ztest_unit_test(test_send_data_blocks),
ztest_unit_test(test_receive_data),
ztest_unit_test(test_receive_data_blocks),
ztest_unit_test(test_send_timeouts),
ztest_unit_test(test_receive_timeouts),
ztest_unit_test(test_stmin),
ztest_unit_test(test_receiver_fc_errors),
ztest_unit_test(test_sender_fc_errors)
);
ztest_run_test_suite(isotp_conformance);
}

View file

@ -0,0 +1,95 @@
/*
* Copyright (c) 2019 Alexander Wachter
*
* SPDX-License-Identifier: Apache-2.0
*/
static const u8_t random_data[] = {
0xdc, 0x70, 0xfa, 0x96, 0xbb, 0x71, 0x49, 0x06, 0x18, 0x75, 0x84, 0xaf,
0xe3, 0xd4, 0x60, 0x11, 0xf8, 0xf8, 0xfa, 0xc7, 0x67, 0xae, 0xa4, 0x36,
0x08, 0xe5, 0x76, 0xa6, 0x50, 0x98, 0x2e, 0xc1, 0x4f, 0x91, 0x90, 0x92,
0xbf, 0xfa, 0x5a, 0xce, 0x6d, 0xeb, 0x2e, 0x5c, 0x77, 0x6b, 0x90, 0xfc,
0x50, 0xd7, 0x69, 0x04, 0x4b, 0x1d, 0xb3, 0x54, 0x55, 0xba, 0x0f, 0x75,
0xf5, 0x3b, 0x0c, 0x76, 0xc8, 0x31, 0x7d, 0x9a, 0xb5, 0xcd, 0x4f, 0x70,
0x47, 0xa0, 0xe3, 0xe5, 0x68, 0x59, 0xfb, 0x1e, 0x20, 0x4a, 0x9c, 0x90,
0xb6, 0xe7, 0x45, 0x83, 0x8d, 0x71, 0xd7, 0x27, 0xac, 0xef, 0xa3, 0xb9,
0x39, 0xda, 0x30, 0xac, 0xc3, 0x3a, 0x1c, 0x7c, 0x29, 0x2f, 0xc6, 0xa0,
0xbc, 0xe1, 0x1d, 0xab, 0x0f, 0x16, 0x30, 0xa4, 0x3c, 0x5d, 0x10, 0x45,
0x38, 0xc0, 0x82, 0x21, 0xad, 0x4c, 0xb3, 0x27, 0xa8, 0xe8, 0x86, 0xa3,
0x2a, 0xa1, 0xfb, 0x06, 0xab, 0xa8, 0x95, 0xab, 0xcf, 0x3b, 0x9f, 0x4e,
0xfa, 0x09, 0xf3, 0x9b, 0x2d, 0x53, 0x1f, 0x8f, 0x00, 0x36, 0x7d, 0x91,
0xd7, 0xf5, 0xc5, 0x81, 0x62, 0x8c, 0x7e, 0xed, 0x01, 0x2a, 0x8d, 0x8c,
0x0b, 0xb8, 0x32, 0x48, 0xad, 0x75, 0xd2, 0xb9, 0xf0, 0x8e, 0xac, 0x1e,
0xfd, 0x3a, 0xac, 0x80, 0xb5, 0x68, 0xf0, 0x84, 0xdc, 0xdf, 0xa9, 0x5a,
0x76, 0x39, 0xee, 0x7e, 0xd5, 0x46, 0xbc, 0xa5, 0x2d, 0x6c, 0x6f, 0x21,
0x3a, 0x23, 0xe1, 0x82, 0x68, 0x4d, 0x67, 0xf9, 0xc4, 0x9b, 0xed, 0x77,
0x9c, 0x5a, 0xc2, 0x09, 0x95, 0xd7, 0x0a, 0x21, 0x94, 0xa7, 0xab, 0x7b,
0xa9, 0xce, 0xce, 0xc6, 0x7e, 0x55, 0xba, 0x22, 0xe5, 0x6c, 0xd5, 0x28,
0x8e, 0x9f, 0x23, 0x5f, 0x68, 0xd3, 0xb9, 0x46, 0x3c, 0x43, 0xcb, 0xe8,
0x9f, 0x7d, 0xb2, 0x08, 0xc8, 0xd6, 0xf8, 0xfa, 0x4e, 0x97, 0xb2, 0x6e,
0x84, 0x0f, 0x1e, 0xfa, 0x17, 0xcb, 0x63, 0xb9, 0xdd, 0xbe, 0xf1, 0x34,
0x72, 0xbb, 0xe5, 0x13, 0xd5, 0x7e, 0x02, 0xd1, 0x06, 0x15, 0x50, 0xd5,
0x7c, 0x91, 0xd5, 0x29, 0x72, 0x58, 0x52, 0x98, 0xb3, 0xa4, 0x4b, 0x54,
0x12, 0xbc, 0xa2, 0xd1, 0xb5, 0x50, 0x33, 0xe2, 0x81, 0xc2, 0x1a, 0x7a,
0xf2, 0xf8, 0xe6, 0x61, 0xa3, 0x96, 0xdb, 0xea, 0x39, 0x84, 0xbb, 0x76,
0x0e, 0xe7, 0x42, 0x6f, 0xee, 0x24, 0x16, 0x33, 0xb1, 0x30, 0x75, 0x9c,
0x97, 0xf0, 0x34, 0x21, 0xea, 0x60, 0xcd, 0x2e, 0x22, 0x51, 0xa4, 0x0a,
0x27, 0xd3, 0x6a, 0x36, 0xe2, 0x55, 0xb3, 0xec, 0x6d, 0x99, 0x1a, 0x26,
0xe6, 0xe0, 0xc3, 0x34, 0x98, 0x8a, 0x95, 0x06, 0x03, 0xa7, 0xc1, 0x4d,
0x28, 0x25, 0x4d, 0xbd, 0xd3, 0x72, 0xc2, 0x5d, 0x0b, 0xf4, 0x98, 0x52,
0x27, 0xe0, 0x56, 0xaf, 0xa8, 0x63, 0xa0, 0x7a, 0x63, 0xbb, 0xb3, 0x18,
0x64, 0xe4, 0xcb, 0x7a, 0x3b, 0xf3, 0x66, 0x44, 0x54, 0xc7, 0xd0, 0x48,
0xb6, 0x00, 0xed, 0x1c, 0xa2, 0xec, 0x4b, 0x72, 0x0a, 0xb0, 0x7e, 0x27,
0x25, 0x77, 0x75, 0xa0, 0x94, 0xaf, 0xb2, 0x97, 0xfc, 0x1d, 0xb2, 0xfb,
0x4b, 0x3a, 0x09, 0x7f, 0x90, 0x05, 0xa0, 0x1d, 0x5f, 0x89, 0x95, 0xb8,
0x1c, 0x50, 0xa2, 0xfa, 0xd9, 0xf5, 0x20, 0x44, 0x99, 0x28, 0x17, 0xa2,
0x5c, 0x5e, 0x02, 0x4d, 0xa1, 0xd1, 0xb4, 0xac, 0x77, 0x45, 0xb8, 0x74,
0xd7, 0xe6, 0xcf, 0x32, 0xee, 0x70, 0x04, 0x05, 0x94, 0x6a, 0x48, 0x8f,
0xcc, 0x1f, 0xf1, 0xc8, 0x92, 0xee, 0xdd, 0xd1, 0x5b, 0x1b, 0xe6, 0x4c,
0x1d, 0x10, 0xf8, 0xc7, 0x1e, 0xc9, 0x8d, 0xbb, 0xf2, 0x30, 0x90, 0x05,
0x5c, 0x07, 0x3c, 0x3e, 0x19, 0xf2, 0xcd, 0x3b, 0xe2, 0x4a, 0xfc, 0xc1,
0xc3, 0x60, 0x64, 0x5c, 0xd0, 0xdf, 0xf7, 0xe3, 0x0d, 0x22, 0xc3, 0x73,
0x08, 0x29, 0x6c, 0x31, 0xa5, 0x2f, 0x99, 0x7a, 0x5c, 0x62, 0x24, 0xb9,
0xe2, 0xb2, 0x0f, 0xc2, 0x32, 0x5d, 0x9e, 0x30, 0x9c, 0xe8, 0x31, 0xd4,
0x4c, 0x63, 0xfd, 0x08, 0x1c, 0x79, 0xbe, 0xea, 0x04, 0xae, 0x31, 0x82,
0x10, 0xd2, 0xf9, 0x05, 0x37, 0x0c, 0x6b, 0xce, 0x1d, 0x5b, 0xdd, 0x0b,
0xdd, 0x4d, 0x1f, 0x47, 0x08, 0xea, 0xf3, 0xf9, 0xd0, 0x5a, 0xf8, 0xf7,
0x12, 0xdf, 0x6e, 0xe8, 0x80, 0xc5, 0x12, 0x27, 0x2d, 0x31, 0xa5, 0xa5,
0x32, 0xb0, 0x1c, 0x83, 0x0f, 0x49, 0xec, 0x95, 0x7a, 0x99, 0x41, 0x97,
0x75, 0x37, 0x64, 0x0c, 0x47, 0x80, 0x7a, 0xe7, 0x13, 0xca, 0xf6, 0x04,
0x18, 0x5d, 0xc3, 0xb3, 0x00, 0x6a, 0x20, 0x96, 0xfb, 0x54, 0x70, 0xa6,
0x77, 0x65, 0xdd, 0x61, 0x5e, 0x0e, 0xd8, 0x53, 0x61, 0x57, 0x8b, 0x0e,
0xa3, 0xc0, 0x30, 0x92, 0xa9, 0xff, 0x13, 0xda, 0xac, 0x5f, 0x38, 0x2c,
0x85, 0xba, 0x79, 0x75, 0x01, 0x65, 0x52, 0xe0, 0x8a, 0x3c, 0x1b, 0xe5,
0x61, 0x79, 0x22, 0xb9, 0x37, 0x44, 0x29, 0x0d, 0x8a, 0xc3, 0x6c, 0x2f,
0x2c, 0x78, 0xcb, 0xab, 0x45, 0x84, 0xb5, 0x88, 0x3a, 0x87, 0x8e, 0x1e,
0x83, 0x02, 0x15, 0x2e, 0x8d, 0x4c, 0x95, 0xbd, 0x38, 0x83, 0xda, 0xa1,
0x9f, 0x6b, 0x41, 0xb4, 0x4a, 0x19, 0x3c, 0x6c, 0xca, 0xd2, 0xc2, 0x89,
0x80, 0x02, 0xd9, 0x41, 0xf6, 0xdc, 0x63, 0x1d, 0x9b, 0x25, 0x25, 0x8b,
0x45, 0xc2, 0x8f, 0x92, 0x1f, 0xf0, 0xe5, 0x0b, 0x42, 0xfc, 0x70, 0x0e,
0xf1, 0x73, 0x44, 0xaa, 0x02, 0xb6, 0x46, 0x71, 0x1d, 0x8a, 0x2c, 0x84,
0xca, 0x48, 0x61, 0x30, 0x44, 0xff, 0x4c, 0xa2, 0x85, 0x98, 0xda, 0x64,
0x67, 0x3d, 0xef, 0xbe, 0xe4, 0xa8, 0x14, 0x8a, 0xda, 0x63, 0xf3, 0x66,
0x39, 0x07, 0x97, 0xdd, 0x5f, 0xea, 0x00, 0x52, 0x56, 0x1a, 0xc9, 0xbc,
0x87, 0xf3, 0x93, 0xda, 0x30, 0xaf, 0x82, 0x87, 0xb0, 0x8e, 0xa5, 0x60,
0x39, 0xf7, 0xd0, 0x15, 0x29, 0xc9, 0x82, 0xe8, 0xe0, 0x95, 0x25, 0x51,
0x70, 0xa3, 0x67, 0xae, 0x37, 0x62, 0x5d, 0xac, 0x73, 0x7f, 0x77, 0x8d,
0xc7, 0xa1, 0x82, 0xf3, 0x69, 0xd9, 0x95, 0x93, 0x83, 0x95, 0x37, 0x17,
0x86, 0x13, 0x5b, 0xb2, 0x82, 0x4a, 0x5b, 0xe3, 0x9b, 0xed, 0x16, 0x9b,
0x8e, 0x25, 0xc8, 0x64, 0xb0, 0x82, 0x16, 0x16, 0xa0, 0x79, 0x7b, 0x0a,
0xbb, 0xd6, 0xa2, 0x27, 0x6e, 0x07, 0x5b, 0x48, 0x48, 0x49, 0xff, 0x67,
0x47, 0x4c, 0xe9, 0xea, 0xe0, 0xf8, 0x15, 0x1f, 0x63, 0xaf, 0x41, 0xa6,
0xed, 0xd4, 0x3e, 0x68, 0x2a, 0xdf, 0x1b, 0x8f, 0x68, 0x16, 0xe2, 0xb7,
0x3a, 0x7e, 0x57, 0x18, 0x81, 0x6b, 0xb6, 0xb3, 0x35, 0x30, 0x55, 0xf3,
0xf9, 0xc9, 0xe6, 0x58, 0x78, 0xa6, 0xf3, 0x02, 0x3e, 0x3c, 0x35, 0x10,
0x41, 0x2c, 0x6e, 0x2c, 0x5b, 0xb2, 0x1c, 0x66, 0xbd, 0x1f, 0x4b, 0xd9,
0x87, 0xcd, 0x54, 0x1b, 0x1e, 0x9a, 0x92, 0xdc, 0x82, 0xae, 0x1c, 0xbc,
0x2f, 0xea, 0x9d, 0x35, 0xdc, 0x3f, 0x9b, 0x18, 0xa2, 0x94, 0x59, 0xd0,
0xea, 0x80, 0xa6, 0xb0, 0xf7, 0x63, 0x6f, 0x4d, 0x63, 0x03, 0x14, 0x94,
0x00, 0x48, 0x7f, 0xbc, 0xe0, 0xb3, 0x52, 0xbc, 0x09, 0xa9, 0x33, 0x51,
0x05, 0xf0, 0x2b, 0x6c, 0xad, 0x78, 0xd0, 0xe5, 0x89, 0xc0, 0x94, 0x49,
0x62, 0xb9, 0x04, 0x71, 0x13, 0xb1, 0x2b, 0x24, 0xcb, 0x6b, 0x2b, 0x71,
0xde, 0x58, 0x8a, 0x01, 0x4c, 0x95, 0x63, 0xa1, 0x29, 0xcb, 0x66, 0x83,
0x58, 0x5c, 0x9e, 0x04
};
unsigned int random_data_len = 1024;

View file

@ -0,0 +1,4 @@
tests:
can.isotp.conformance:
tags: can isotp
depends_on: can

View file

@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.13.1)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(integration)
FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})

View file

@ -0,0 +1,8 @@
CONFIG_CAN=y
CONFIG_ZTEST=y
CONFIG_ISOTP=y
CONFIG_ISOTP_USE_TX_BUF=y
CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS=y
CONFIG_ISOTP_RX_BUF_COUNT=2
CONFIG_ISOTP_RX_BUF_SIZE=56
CONFIG_ISOTP_RX_SF_FF_BUF_COUNT=2

View file

@ -0,0 +1,440 @@
/*
* Copyright (c) 2019 Alexander Wachter
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <canbus/isotp.h>
#include <ztest.h>
#include <strings.h>
#include "random_data.h"
#include <net/buf.h>
#define NUMBER_OF_REPETITIONS 5
#define DATA_SIZE_SF 7
#if defined(CONFIG_CAN_LOOPBACK_DEV_NAME)
#define CAN_DEVICE_NAME CONFIG_CAN_LOOPBACK_DEV_NAME
#else
#define CAN_DEVICE_NAME DT_ALIAS_CAN_PRIMARY_LABEL
#endif
/*
* @addtogroup t_can
* @{
* @defgroup t_can_isotp test_can_isotp
* @brief TestPurpose: struggle the implementation and see if it breaks apart.
* @details
* - Test Steps
* -#
* - Expected Results
* -#
* @}
*/
struct device *can_dev;
const struct isotp_fc_opts fc_opts = {
.bs = 8,
.stmin = 0
};
const struct isotp_fc_opts fc_opts_single = {
.bs = 0,
.stmin = 1
};
const struct isotp_msg_id rx_addr = {
.std_id = 0x10,
.id_type = CAN_STANDARD_IDENTIFIER,
.use_ext_addr = 0
};
const struct isotp_msg_id tx_addr = {
.std_id = 0x11,
.id_type = CAN_STANDARD_IDENTIFIER,
.use_ext_addr = 0
};
struct isotp_recv_ctx recv_ctx;
struct isotp_send_ctx send_ctx;
u8_t data_buf[128];
void send_complette_cb(int error_nr, void *arg)
{
zassert_equal(error_nr, ISOTP_N_OK, "Sending failed (%d)", error_nr);
}
static void send_sf(struct device *can_dev)
{
int ret;
ret = isotp_send(&send_ctx, can_dev, random_data, DATA_SIZE_SF,
&rx_addr, &tx_addr, send_complette_cb, NULL);
zassert_equal(ret, 0, "Send returned %d", ret);
}
static void get_sf_net(struct isotp_recv_ctx *recv_ctx)
{
struct net_buf *buf;
int remaining_len, ret;
remaining_len = isotp_recv_net(recv_ctx, &buf, K_MSEC(1000));
zassert_true(remaining_len >= 0, "recv returned %d", remaining_len);
zassert_equal(remaining_len, 0, "SF should fit in one frame");
zassert_equal(buf->len, DATA_SIZE_SF, "Data length (%d) should be %d.",
buf->len, DATA_SIZE_SF);
ret = memcmp(random_data, buf->data, buf->len);
zassert_equal(ret, 0, "received data differ");
memset(buf->data, 0, buf->len);
net_buf_unref(buf);
}
static void get_sf(struct isotp_recv_ctx *recv_ctx)
{
int ret;
u8_t *data_buf_ptr = data_buf;
memset(data_buf, 0, sizeof(data_buf));
ret = isotp_recv(recv_ctx, data_buf_ptr++, 1, K_MSEC(1000));
zassert_equal(ret, 1, "recv returned %d", ret);
ret = isotp_recv(recv_ctx, data_buf_ptr++, sizeof(data_buf) - 1,
K_MSEC(1000));
zassert_equal(ret, DATA_SIZE_SF - 1, "recv returned %d", ret);
ret = memcmp(random_data, data_buf, DATA_SIZE_SF);
zassert_equal(ret, 0, "received data differ");
}
void print_hex(const u8_t *ptr, size_t len)
{
while (len--) {
printk("%02x", *ptr++);
}
}
static void send_test_data(struct device *can_dev, const u8_t *data, size_t len)
{
int ret;
ret = isotp_send(&send_ctx, can_dev, data, len, &rx_addr, &tx_addr,
send_complette_cb, NULL);
zassert_equal(ret, 0, "Send returned %d", ret);
}
static const u8_t *check_frag(struct net_buf *frag, const u8_t *data)
{
int ret;
ret = memcmp(data, frag->data, frag->len);
if (ret) {
printk("expected bytes:\n");
print_hex(data, frag->len);
printk("\nreceived (%d bytes):\n", frag->len);
print_hex(frag->data, frag->len);
printk("\n");
}
zassert_equal(ret, 0, "Received data differ");
return data + frag->len;
}
static void receive_test_data_net(struct isotp_recv_ctx *recv_ctx,
const u8_t *data, size_t len, s32_t delay)
{
int remaining_len;
size_t received_len = 0;
const u8_t *data_ptr = data;
struct net_buf *buf;
do {
remaining_len = isotp_recv_net(recv_ctx, &buf, K_MSEC(1000));
zassert_true(remaining_len >= 0, "recv error: %d",
remaining_len);
received_len += buf->len;
zassert_equal(received_len + remaining_len, len,
"Length missmatch");
data_ptr = check_frag(buf, data_ptr);
if (delay) {
k_sleep(delay);
}
memset(buf->data, 0, buf->len);
net_buf_unref(buf);
} while (remaining_len);
remaining_len = isotp_recv_net(recv_ctx, &buf, K_MSEC(50));
zassert_equal(remaining_len, ISOTP_RECV_TIMEOUT,
"Expected timeout but got %d", remaining_len);
}
static void check_data(const u8_t *recv_data, const u8_t *send_data, size_t len)
{
int ret;
ret = memcmp(send_data, recv_data, len);
if (ret) {
printk("expected bytes:\n");
print_hex(send_data, len);
printk("\nreceived (%d bytes):\n", len);
print_hex(recv_data, len);
printk("\n");
}
zassert_equal(ret, 0, "Received data differ");
}
static void receive_test_data(struct isotp_recv_ctx *recv_ctx,
const u8_t *data, size_t len, s32_t delay)
{
size_t remaining_len = len;
int ret;
const u8_t *data_ptr = data;
do {
memset(data_buf, 0, sizeof(data_buf));
ret = isotp_recv(recv_ctx, data_buf, sizeof(data_buf),
K_MSEC(1000));
zassert_true(data_buf >= 0, "recv error: %d", ret);
zassert_true(remaining_len >= ret, "More data then expected");
check_data(data_buf, data_ptr, ret);
data_ptr += ret;
remaining_len -= ret;
if (delay) {
k_sleep(delay);
}
} while (remaining_len);
ret = isotp_recv(recv_ctx, data_buf, sizeof(data_buf), K_MSEC(50));
zassert_equal(ret, ISOTP_RECV_TIMEOUT,
"Expected timeout but got %d", ret);
}
static void test_send_receive_net_sf(void)
{
int ret, i;
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr, &fc_opts,
K_NO_WAIT);
zassert_equal(ret, 0, "Bind returned %d", ret);
for (i = 0; i < NUMBER_OF_REPETITIONS; i++) {
send_sf(can_dev);
get_sf_net(&recv_ctx);
}
isotp_unbind(&recv_ctx);
}
static void test_send_receive_sf(void)
{
int ret, i;
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr, &fc_opts,
K_NO_WAIT);
zassert_equal(ret, 0, "Bind returned %d", ret);
for (i = 0; i < NUMBER_OF_REPETITIONS; i++) {
send_sf(can_dev);
get_sf(&recv_ctx);
}
isotp_unbind(&recv_ctx);
}
static void test_send_receive_net_blocks(void)
{
int ret, i;
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr, &fc_opts,
K_NO_WAIT);
zassert_equal(ret, 0, "Binding failed (%d)", ret);
for (i = 0; i < NUMBER_OF_REPETITIONS; i++) {
send_test_data(can_dev, random_data, random_data_len);
receive_test_data_net(&recv_ctx, random_data,
random_data_len, 0);
}
isotp_unbind(&recv_ctx);
}
static void test_send_receive_blocks(void)
{
const size_t data_size = sizeof(data_buf) * 2 + 10;
int ret, i;
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr, &fc_opts,
K_NO_WAIT);
zassert_equal(ret, 0, "Binding failed (%d)", ret);
for (i = 0; i < NUMBER_OF_REPETITIONS; i++) {
send_test_data(can_dev, random_data, data_size);
receive_test_data(&recv_ctx, random_data, data_size, 0);
}
isotp_unbind(&recv_ctx);
}
static void test_send_receive_net_single_blocks(void)
{
const size_t send_len = CONFIG_ISOTP_RX_BUF_COUNT *
CONFIG_ISOTP_RX_BUF_SIZE + 6;
int ret, i;
size_t buf_len;
struct net_buf *buf, *frag;
const u8_t *data_ptr;
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
&fc_opts_single, K_NO_WAIT);
zassert_equal(ret, 0, "Binding failed (%d)", ret);
for (i = 0; i < NUMBER_OF_REPETITIONS; i++) {
send_test_data(can_dev, random_data, send_len);
data_ptr = random_data;
ret = isotp_recv_net(&recv_ctx, &buf, K_MSEC(1000));
zassert_equal(ret, 0, "recv returned %d", ret);
buf_len = net_buf_frags_len(buf);
zassert_equal(buf_len, send_len, "Data length differ");
frag = buf;
do {
data_ptr = check_frag(frag, data_ptr);
memset(frag->data, 0, frag->len);
} while ((frag = frag->frags));
net_buf_unref(buf);
}
isotp_unbind(&recv_ctx);
}
static void test_send_receive_single_block(void)
{
const size_t send_len = CONFIG_ISOTP_RX_BUF_COUNT *
CONFIG_ISOTP_RX_BUF_SIZE + 6;
int ret, i;
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
&fc_opts_single, K_NO_WAIT);
zassert_equal(ret, 0, "Binding failed (%d)", ret);
for (i = 0; i < NUMBER_OF_REPETITIONS; i++) {
send_test_data(can_dev, random_data, send_len);
memset(data_buf, 0, sizeof(data_buf));
ret = isotp_recv(&recv_ctx, data_buf, sizeof(data_buf),
K_MSEC(1000));
zassert_equal(ret, send_len,
"data should be received at once (ret: %d)", ret);
ret = memcmp(random_data, data_buf, send_len);
zassert_equal(ret, 0, "Data differ");
}
isotp_unbind(&recv_ctx);
}
static void test_bind_unbind(void)
{
int ret, i;
for (i = 0; i < 100; i++) {
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
&fc_opts, K_NO_WAIT);
zassert_equal(ret, 0, "Binding failed (%d)", ret);
isotp_unbind(&recv_ctx);
}
for (i = 0; i < NUMBER_OF_REPETITIONS; i++) {
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
&fc_opts, K_NO_WAIT);
zassert_equal(ret, 0, "Binding failed (%d)", ret);
send_sf(can_dev);
get_sf_net(&recv_ctx);
isotp_unbind(&recv_ctx);
}
for (i = 0; i < NUMBER_OF_REPETITIONS; i++) {
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
&fc_opts, K_NO_WAIT);
zassert_equal(ret, 0, "Binding failed (%d)", ret);
send_sf(can_dev);
get_sf(&recv_ctx);
isotp_unbind(&recv_ctx);
}
for (i = 0; i < 10; i++) {
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
&fc_opts, K_NO_WAIT);
zassert_equal(ret, 0, "Binding failed (%d)", ret);
send_test_data(can_dev, random_data, 60);
receive_test_data_net(&recv_ctx, random_data, 60, 0);
isotp_unbind(&recv_ctx);
}
for (i = 0; i < NUMBER_OF_REPETITIONS; i++) {
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr,
&fc_opts, K_NO_WAIT);
zassert_equal(ret, 0, "Binding failed (%d)", ret);
send_test_data(can_dev, random_data, 60);
receive_test_data(&recv_ctx, random_data, 60, 0);
isotp_unbind(&recv_ctx);
}
}
static void test_buffer_allocation(void)
{
int ret;
size_t send_data_length = CONFIG_ISOTP_RX_BUF_COUNT *
CONFIG_ISOTP_RX_BUF_SIZE * 3 + 6;
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr, &fc_opts,
K_NO_WAIT);
zassert_equal(ret, 0, "Binding failed (%d)", ret);
send_test_data(can_dev, random_data, send_data_length);
k_sleep(K_MSEC(100));
receive_test_data_net(&recv_ctx, random_data, send_data_length, 200);
isotp_unbind(&recv_ctx);
}
static void test_buffer_allocation_wait(void)
{
int ret;
size_t send_data_length = CONFIG_ISOTP_RX_BUF_COUNT *
CONFIG_ISOTP_RX_BUF_SIZE * 2 + 6;
ret = isotp_bind(&recv_ctx, can_dev, &rx_addr, &tx_addr, &fc_opts,
K_NO_WAIT);
zassert_equal(ret, 0, "Binding failed (%d)", ret);
send_test_data(can_dev, random_data, send_data_length);
k_sleep(K_MSEC(100));
receive_test_data_net(&recv_ctx, random_data, send_data_length, 2000);
isotp_unbind(&recv_ctx);
}
void test_main(void)
{
int ret;
zassert_true(sizeof(random_data) >= sizeof(data_buf) * 2 + 10,
"Test data size to small");
can_dev = device_get_binding(CAN_DEVICE_NAME);
zassert_not_null(can_dev, "CAN device not not found");
ret = can_configure(can_dev, CAN_LOOPBACK_MODE, 0);
zassert_equal(ret, 0, "Configuring loopback mode failed (%d)", ret);
ztest_test_suite(isotp,
ztest_unit_test(test_bind_unbind),
ztest_unit_test(test_send_receive_net_sf),
ztest_unit_test(test_send_receive_net_blocks),
ztest_unit_test(test_send_receive_net_single_blocks),
ztest_unit_test(test_send_receive_sf),
ztest_unit_test(test_send_receive_blocks),
ztest_unit_test(test_send_receive_single_block),
ztest_unit_test(test_buffer_allocation),
ztest_unit_test(test_buffer_allocation_wait)
);
ztest_run_test_suite(isotp);
}

View file

@ -0,0 +1,95 @@
/*
* Copyright (c) 2019 Alexander Wachter
*
* SPDX-License-Identifier: Apache-2.0
*/
static const u8_t random_data[] = {
0x17, 0xee, 0x94, 0x6b, 0xb0, 0x3c, 0x0d, 0x75, 0x0f, 0x25, 0x49, 0x6a,
0x88, 0x08, 0x1d, 0x14, 0x65, 0x2a, 0xdb, 0x8d, 0xaa, 0xc8, 0x4e, 0x2e,
0x3a, 0x0e, 0xe8, 0x79, 0xcd, 0x0d, 0x8f, 0x20, 0xac, 0x18, 0xeb, 0x78,
0xa3, 0xdd, 0x0d, 0x76, 0x90, 0x64, 0x8f, 0x42, 0x93, 0xfd, 0x8d, 0xfe,
0x96, 0x60, 0xc5, 0x9c, 0xb9, 0xc1, 0x86, 0x41, 0x99, 0x6c, 0x5f, 0x5c,
0x6e, 0xdb, 0xbb, 0x49, 0x63, 0x18, 0xf9, 0x90, 0x6e, 0x8e, 0xcb, 0x1e,
0xd1, 0x59, 0xcf, 0x50, 0x65, 0x10, 0x29, 0xeb, 0x81, 0x91, 0xa6, 0xc2,
0xd7, 0x7b, 0xf6, 0xbf, 0xac, 0x42, 0x71, 0x1d, 0x43, 0xb9, 0x72, 0x18,
0x8e, 0xcf, 0xdc, 0x6c, 0x13, 0x70, 0x1d, 0xfa, 0xb0, 0x53, 0x57, 0xb0,
0x6c, 0x89, 0x42, 0xe9, 0x0a, 0x2f, 0xcd, 0x89, 0x74, 0x55, 0x77, 0xdc,
0x7e, 0x8c, 0xa6, 0x7c, 0xe9, 0xc8, 0xda, 0xfa, 0x00, 0x32, 0x2b, 0x89,
0x66, 0x3f, 0x9f, 0xdf, 0xb0, 0x15, 0xbe, 0x40, 0xcf, 0x0d, 0x01, 0x83,
0xb0, 0xc8, 0xc6, 0xba, 0x58, 0xe3, 0xf0, 0x78, 0x18, 0x91, 0x42, 0x78,
0xc7, 0x72, 0x1f, 0x4a, 0x75, 0xea, 0xf5, 0xeb, 0x49, 0xd0, 0xca, 0xc6,
0xd6, 0x84, 0x17, 0x8c, 0x2d, 0xf6, 0x8f, 0xc2, 0x27, 0x53, 0xc5, 0xd0,
0x6a, 0x9c, 0x64, 0x08, 0x98, 0xa8, 0xe8, 0x48, 0x34, 0x06, 0x00, 0xdb,
0xed, 0xe4, 0xa1, 0x29, 0x1a, 0xd6, 0x2c, 0x13, 0x2f, 0x1d, 0x40, 0x3e,
0x12, 0x39, 0x6a, 0x7b, 0x16, 0x76, 0x09, 0xe5, 0x13, 0xeb, 0xd2, 0xbf,
0x92, 0x27, 0x46, 0x12, 0xeb, 0xf5, 0xfe, 0x54, 0xd1, 0xda, 0xfa, 0xbc,
0x5b, 0x56, 0x73, 0x5e, 0xcd, 0xad, 0x04, 0x82, 0x11, 0x9a, 0xb2, 0x28,
0xc2, 0xf5, 0x77, 0xf3, 0xbf, 0xe2, 0xc3, 0xdc, 0x28, 0xb7, 0x58, 0x0c,
0x01, 0xf3, 0x5c, 0x03, 0x00, 0xd3, 0x34, 0x2a, 0x06, 0xa1, 0xa0, 0x12,
0xeb, 0x0f, 0x19, 0x5d, 0xce, 0x30, 0x82, 0x77, 0xf6, 0xe1, 0x46, 0x15,
0xab, 0xb2, 0x2e, 0x0e, 0x4d, 0x18, 0x4e, 0x95, 0x03, 0x27, 0xa9, 0xb1,
0x5a, 0x21, 0x6c, 0x00, 0x10, 0x70, 0x9f, 0x73, 0x76, 0x57, 0x50, 0xa2,
0xb1, 0x51, 0x1c, 0x84, 0xd3, 0xa9, 0x0e, 0x26, 0xd7, 0x69, 0xaa, 0x90,
0xbd, 0x07, 0xc1, 0x85, 0xc9, 0x66, 0xf6, 0x4e, 0x83, 0x45, 0x2e, 0xb6,
0x57, 0x03, 0x04, 0x8f, 0x10, 0x11, 0xc4, 0xbd, 0x39, 0x81, 0x71, 0x2d,
0xc1, 0x09, 0xd7, 0x17, 0x11, 0x21, 0x60, 0x0f, 0xab, 0xe4, 0xa6, 0x4c,
0xa3, 0x42, 0x6d, 0x1f, 0x44, 0xbb, 0x86, 0x40, 0x73, 0xbb, 0xc5, 0x26,
0xdc, 0x5f, 0x87, 0xbb, 0x86, 0x92, 0x18, 0x2c, 0x0d, 0x19, 0xeb, 0x18,
0x9c, 0x5b, 0xeb, 0x7e, 0xd2, 0x2b, 0xe3, 0xa7, 0x0c, 0x97, 0x95, 0x34,
0x33, 0x9b, 0x7e, 0xbf, 0x57, 0xe0, 0x08, 0x69, 0x62, 0x67, 0x36, 0x5d,
0x35, 0x35, 0x7f, 0x97, 0xed, 0x89, 0x08, 0x55, 0x3b, 0x34, 0x3a, 0xae,
0xb0, 0x34, 0x1e, 0xcb, 0x1b, 0x6f, 0x5a, 0x6b, 0xef, 0xb0, 0x52, 0xd1,
0xc4, 0xa2, 0xc4, 0x8f, 0x23, 0x8e, 0x87, 0xb8, 0x4a, 0xe7, 0x3f, 0x33,
0xa0, 0x33, 0xbe, 0x4b, 0x87, 0xed, 0xff, 0x92, 0xda, 0xcc, 0x27, 0xa3,
0xab, 0x8e, 0x28, 0x99, 0x64, 0x4a, 0x50, 0xc5, 0xd0, 0x2d, 0x5b, 0x4b,
0xdb, 0xff, 0xc6, 0x18, 0xda, 0x26, 0xcb, 0x7d, 0x48, 0x36, 0x31, 0x50,
0x94, 0xc9, 0x16, 0xf4, 0xdb, 0xcc, 0x4e, 0x21, 0x9a, 0x7a, 0x4b, 0x03,
0x98, 0x50, 0x12, 0x15, 0x0d, 0x6e, 0x97, 0x92, 0x68, 0xdc, 0x5a, 0xd1,
0x07, 0x3e, 0x29, 0xb5, 0xf1, 0x74, 0xd5, 0x1e, 0xa2, 0x6c, 0x92, 0xf9,
0x76, 0xe6, 0x1c, 0x78, 0xd5, 0xce, 0x37, 0x3a, 0x92, 0xfa, 0xb2, 0xaf,
0x69, 0xd9, 0xf7, 0x67, 0xc1, 0x15, 0x14, 0xd5, 0x96, 0x0c, 0xcf, 0x4b,
0x2d, 0xa9, 0x93, 0x69, 0x83, 0x97, 0x99, 0xec, 0xae, 0xa9, 0xb5, 0x24,
0xd8, 0xae, 0x64, 0xda, 0x32, 0xaf, 0x53, 0x27, 0xa3, 0xdf, 0x9e, 0x23,
0x40, 0xcb, 0x14, 0xa8, 0x00, 0x52, 0x11, 0x56, 0x9f, 0xfe, 0x5e, 0x77,
0x46, 0x31, 0xf8, 0xcb, 0x04, 0x43, 0xad, 0xe1, 0xcf, 0x77, 0x38, 0x80,
0xfd, 0x34, 0xb0, 0xc2, 0xe2, 0xe3, 0x16, 0xef, 0x04, 0x95, 0x4a, 0xd1,
0x8d, 0x8b, 0x12, 0xac, 0x96, 0xa4, 0xe8, 0xdb, 0xe3, 0x01, 0x79, 0xa5,
0xf6, 0x28, 0x8e, 0x2c, 0x50, 0x31, 0xb2, 0xb7, 0x00, 0xc6, 0x81, 0xd1,
0x4d, 0x0a, 0xb5, 0x53, 0xb2, 0xf0, 0x1a, 0x7a, 0x98, 0xae, 0xe5, 0x70,
0x2f, 0xdf, 0x01, 0x0d, 0x8a, 0x07, 0x08, 0x6c, 0xa7, 0x0a, 0xf4, 0xde,
0x64, 0xbf, 0xff, 0x38, 0x2b, 0x9f, 0xdb, 0xd2, 0x5e, 0xf8, 0x14, 0x34,
0x38, 0x9d, 0x86, 0x4f, 0x3e, 0x00, 0x79, 0xe0, 0xb9, 0xdb, 0x5e, 0x53,
0x4f, 0xf5, 0x2b, 0xf0, 0x25, 0x30, 0x40, 0x3d, 0x94, 0x26, 0x7c, 0xf3,
0x2e, 0x1d, 0x63, 0x79, 0x5e, 0x75, 0x54, 0xfb, 0xd5, 0x84, 0x06, 0xe5,
0x13, 0x92, 0xdd, 0xba, 0x98, 0x9a, 0x2d, 0x18, 0x91, 0x4b, 0x27, 0xce,
0xea, 0x12, 0x81, 0x09, 0xf5, 0x1d, 0x31, 0xdb, 0x3a, 0x6d, 0x24, 0xcd,
0xbd, 0x5f, 0xae, 0xcd, 0xad, 0x79, 0x5e, 0xa1, 0x1c, 0xcd, 0xb1, 0x0a,
0xb1, 0x27, 0x1b, 0x76, 0x2a, 0x1d, 0x47, 0x72, 0xe7, 0x5f, 0x88, 0x7a,
0x13, 0x13, 0xf1, 0xcb, 0xbc, 0xb8, 0x04, 0xcd, 0xe9, 0xf0, 0xfb, 0xed,
0x75, 0x63, 0x14, 0xc4, 0x37, 0xf5, 0x29, 0x4b, 0x31, 0x59, 0xbc, 0xa3,
0x34, 0x37, 0x95, 0xaa, 0x88, 0x4a, 0x37, 0xdd, 0xf5, 0x9c, 0xe5, 0xa4,
0xe1, 0x58, 0x69, 0x8e, 0xcf, 0x09, 0xd3, 0x70, 0x60, 0x08, 0xb6, 0x80,
0x3d, 0x2f, 0x98, 0x5a, 0x06, 0x5c, 0x22, 0xa3, 0x19, 0x76, 0x3f, 0xea,
0x4b, 0x7f, 0xef, 0xe8, 0xfa, 0xc9, 0x32, 0xd4, 0xe9, 0x0e, 0xfe, 0x04,
0x04, 0x62, 0x18, 0x8a, 0xf9, 0xd7, 0x42, 0x67, 0xa9, 0x49, 0x45, 0x87,
0xa2, 0x51, 0xce, 0x9c, 0x35, 0x25, 0xf3, 0xa4, 0xcd, 0xb7, 0xd5, 0x6b,
0x0f, 0xd3, 0x0e, 0xb9, 0x46, 0x1e, 0xfe, 0x79, 0x72, 0x6c, 0xfb, 0x5a,
0xf9, 0x35, 0xc0, 0x82, 0x53, 0x1e, 0x7a, 0x20, 0xc8, 0xf5, 0x57, 0x7f,
0x20, 0x54, 0xd7, 0x79, 0x8c, 0x13, 0x7b, 0x7d, 0x0b, 0x3d, 0xf9, 0xcc,
0xa0, 0x70, 0x3d, 0xd3, 0x44, 0x03, 0x7d, 0xf5, 0xd2, 0x3b, 0xdb, 0xac,
0xf4, 0x98, 0x2c, 0xd3, 0xe0, 0x62, 0xbd, 0x93, 0xbc, 0xe3, 0x3c, 0xce,
0x44, 0xde, 0xd9, 0x11, 0x2b, 0xd0, 0x6e, 0x56, 0x4b, 0xd0, 0x64, 0xdb,
0xa5, 0x59, 0x2a, 0xc5, 0xfb, 0xfb, 0x35, 0x87, 0x1a, 0xc0, 0x42, 0x5f,
0x68, 0xce, 0xf4, 0xfc, 0x2b, 0x76, 0x5b, 0xd8, 0x0a, 0x57, 0x5c, 0x89,
0x5f, 0x6f, 0x8c, 0x9a, 0x85, 0xd6, 0x69, 0x19, 0xba, 0xa2, 0x53, 0x4c,
0x71, 0xab, 0xf7, 0x3d, 0xc3, 0x58, 0x26, 0x66, 0x3c, 0x80, 0xc1, 0xd1,
0x0f, 0x78, 0xcb, 0x98, 0x5d, 0xe3, 0xfe, 0xea, 0x5f, 0x7e, 0x57, 0x5e,
0xc3, 0x39, 0xe0, 0x71, 0x32, 0xac, 0xf6, 0x02, 0x24, 0xa4, 0x0b, 0x5c,
0xe4, 0x5a, 0x95, 0x17, 0x87, 0x5e, 0xf0, 0x63, 0xb1, 0x0b, 0x51, 0x6f,
0x76, 0x2b, 0xa6, 0xeb, 0x03, 0x4f, 0xc5, 0xfb, 0xa3, 0x8b, 0xa2, 0xf1,
0x97, 0x52, 0x5d, 0xfe, 0xdc, 0x93, 0x9a, 0x31, 0xeb, 0x2a, 0xac, 0xbb,
0x96, 0x77, 0x0e, 0x88, 0xef, 0x54, 0x9c, 0x0f, 0xa0, 0xd6, 0x52, 0x93,
0x07, 0x3b, 0xa4, 0x96
};
unsigned int random_data_len = 1024;

View file

@ -0,0 +1,4 @@
tests:
can.isotp.implemmentation:
tags: can isotp
depends_on: can