src.dualinventive.com/fw/dncm/libdi/tests/can_framing.cpp

175 lines
4.9 KiB
C++
Executable File

/**
* @file tests/can_framing.cpp
* @brief brief
* @date Aug 25, 2015
* @author rheijden
* @copyright 2015 Dual Inventive Technology Centre B.V.
*
* descr
*/
#include "tests/can.h"
#include <gtest/gtest.h>
#include <di/can.h>
#include <di/can/framing.h>
static struct di_can_ctx can_ctx;
DI_CAN_MSG_DECL_ARRAY(can_msg_list, DI_CAN_CFG_MSG_SIZE, DI_CAN_CFG_MSG_DATA_SIZE);
static size_t g_can_send_bytes = 0;
static size_t g_can_send_frames = 0;
/**
* Test send callback
*/
static di_errno_t test_can_send_cb(const struct di_can_frame_tx *frame)
{
g_can_send_frames += 1;
g_can_send_bytes += frame->size;
return DNOK;
}
/**
* Test send helper function
* @param m Message to send
* @param payload_size Size of the payload in bytes to send
* @param exp_frames Expected frame count to be send
* @param exp_bytes Bytes expected
*/
static void test_send(struct di_can_msg *m, size_t payload_size, size_t exp_frames, size_t exp_bytes) {
const uint8_t transaction_id = DI_CAN_NET_NODE_TYPE_ZKL3000RC_MAIN;
/* Reset framing bytes and frames counter */
g_can_send_bytes = 0;
g_can_send_frames = 0;
m->size = payload_size;
if (payload_size > DI_CAN_FRAMING_SIZE_MAX) {
printf("--- expect: DNE_PROTO, payload_size(%zu) > DI_CAN_FRAMING_SIZE_MAX(%u)\n",
payload_size, DI_CAN_FRAMING_SIZE_MAX);
ASSERT_EQ(DNE_PROTO, di_can_framing_send(&can_ctx, m, transaction_id));
return;
}
printf("--- expect: bytes: %zu, frames: %zu\n",
exp_bytes, exp_frames);
ASSERT_EQ(DNOK, di_can_framing_send(&can_ctx, m, transaction_id));
printf("--- got: bytes: %zu, frames %zu\n",
g_can_send_bytes, g_can_send_frames);
ASSERT_EQ(exp_bytes, g_can_send_bytes);
ASSERT_EQ(exp_frames, g_can_send_frames);
}
/**
* Initialize can stack context
*/
TEST(can_frame, init) {
DI_CAN_MSG_INIT_ARRAY(&can_ctx, can_msg_list, DI_CAN_CFG_MSG_SIZE, DI_CAN_CFG_MSG_DATA_SIZE);
di_can_init(&can_ctx);
di_can_msg_init(&can_ctx, can_msg_list, DI_CAN_CFG_MSG_SIZE);
}
TEST(can_framing, send) {
struct di_can_msg *m;
di_can_callback_set_send(&can_ctx, test_can_send_cb);
/* Get unused message */
m = di_can_msg_alloc(&can_ctx);
ASSERT_NE(nullptr, m);
printf("DI_CAN_FRAMING_SIZE_MAX: %u\n", DI_CAN_FRAMING_SIZE_MAX);
/** Flush buffer, point msg to a valid place
@todo do we really need to flush? */
di_buffer_flush(m->buf);
m->msg = (uint8_t *)m->buf->data;
/** payload_size, frames_expected, bytes_expected */
test_send(m, 0, 1, DI_CAN_FRAME_SIZE); // 1 frame, 0 bytes payload -> SFT, 8 bytes
test_send(m, 1, 3, DI_CAN_MSG_SIZE_MFT + 1); // 3 frames, 1 bytes payload -> MFT, 8 + 5 + 1 bytes
test_send(m, 8, 3, DI_CAN_MSG_SIZE_MFT + 8); // 3 frames, 8 bytes payload -> MFT, 8 + 5 + 8 bytes
test_send(m, 9, 4, DI_CAN_MSG_SIZE_MFT + 9); // 4 frames, 9 bytes payload -> MFT, 8 + 5 + 9 bytes
test_send(m, DI_CAN_FRAMING_SIZE_MAX, DI_CAN_FRAME_ID_MAX_COUNT, DI_CAN_MSG_SIZE_MFT + DI_CAN_FRAME_SIZE * 510);
test_send(m, DI_CAN_FRAMING_SIZE_MAX + 1, DI_CAN_FRAME_ID_MAX_COUNT, DI_CAN_MSG_SIZE_MFT + DI_CAN_FRAME_SIZE * 510);
di_can_msg_free(&m);
}
/**
* Test can framing send fails gracefull
*/
static size_t g_can_send_frames_fail = 0;
/**
* Test send callback (returns error)
*/
static di_errno_t test_can_send_cb_fail(const struct di_can_frame_tx *frame)
{
(void)frame;
if (g_can_send_frames == g_can_send_frames_fail)
return DNE_CAN_IO;
g_can_send_frames++;
return DNOK;
}
/**
* Helper function to test send failed
* Messages <= DI_CAN_FRAMING_SIZE_MAX (1024 bytes, 1KByte) are valid
* Messages > 1KByte trying to frame will result in DNE_CAN_INVAL
* The DNE_CAN_IO error is returned by the callback
*/
static void test_send_fail(struct di_can_msg *m, size_t payload_size, size_t fail_frame_idx) {
g_can_send_frames = 0;
g_can_send_frames_fail = fail_frame_idx;
m->size = payload_size;
m->msg = m->buf->data; /* Message pointer needs to point to the payload to calculate the CRC */
EXPECT_EQ(DNE_CAN_IO, di_can_framing_send(&can_ctx, m, 0));
}
TEST(can_framing, send_fail) {
struct di_can_msg *m;
di_can_callback_set_send(&can_ctx, test_can_send_cb_fail);
m = di_can_msg_alloc(&can_ctx);
ASSERT_NE((void *)NULL, m);
test_send_fail(m, 0, DI_CAN_FRAME_ID_SRC_DST_NODEID);
test_send_fail(m, DI_CAN_FRAME_SIZE, DI_CAN_FRAME_ID_MFT_METADATA);
/* Test di_can_framing_send_payload */
test_send_fail(m, (16 * DI_CAN_FRAME_SIZE), DI_CAN_FRAME_ID_MFT_METADATA + 8);
test_send_fail(m, (16 * DI_CAN_FRAME_SIZE), DI_CAN_FRAME_ID_MFT_METADATA + 15);
test_send_fail(m, (16 * DI_CAN_FRAME_SIZE), DI_CAN_FRAME_ID_MFT_METADATA + 16);
di_can_msg_free(&m);
}
TEST(can_framing, send_mft_meta_crc_error) {
struct di_can_msg *msg = di_can_msg_alloc(&can_ctx);
di_can_callback_set_send(&can_ctx, test_can_send_cb);
ASSERT_NE((void *)NULL, msg);
msg->msg = NULL;
msg->size = 1;
ASSERT_EQ(DNE_CAN_INVAL, di_can_framing_send(&can_ctx, msg, 0));
di_can_msg_free(&msg);
}