src.dualinventive.com/dinet/libdi-php/libdi/tests/can_reassemble.cpp

208 lines
6.5 KiB
C++

/**
* @file tests/can_reassemble.cpp
* @brief brief
* @date Aug 25, 2015
* @author rheijden
* @copyright 2015 Dual Inventive Technology Centre B.V.
*
* descr
*/
#include "fixtures/CANTest.hpp"
#include <di/can.h>
#include <di/can/frame.h>
static void test_dup_buf(struct di_can_msg *msg)
{
size_t lines = msg->size / 16;
for (size_t i = 0; i < lines; i++) {
printf("%04zx : ", i * 16);
for (size_t n = 0; n < 16; n++)
printf("%02x ", *(((uint8_t *)msg->buf->data) + n + (i * 16)));
for (size_t n = 0; n < 16; n++) {
if (isgraph(*(((uint8_t *)msg->buf->data) + n + (i * 16))))
putc(*(((uint8_t *)msg->buf->data) + n + (i * 16)), stdout);
else
putc('.', stdout);
}
printf("\n");
}
}
void test_msg_dump(struct di_can_msg *msg)
{
printf(" size: %zu\n", msg->size);
test_dup_buf(msg);
}
/**
* Null frames (canid == 0, size == 0) should not crash the stack
*/
static di_errno_t recv_cb_reassemble_null_frames(struct di_can_frame_rx *frame)
{
frame->canid = 0;
frame->size = 0;
return DNOK;
}
TEST_F(DI_CAN, reassemble_null_frames) {
di_can_callback_set_recv(&_ctx, recv_cb_reassemble_null_frames);
for (size_t n = 0; n < 8; n++)
di_can_lowlevel_recv(&_ctx);
di_can_reassemble(&_ctx);
}
/**
* Check if SFT message is correctly reassembled
*/
static di_errno_t recv_cb_sft_frame(struct di_can_frame_rx *frame)
{
uint8_t data[8] = {0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xba, 0xbe};
frame->canid = 0x01230001;
frame->size = sizeof(data);
memcpy(frame->buf, &data, sizeof(data));
return DNOK;
}
TEST_F(DI_CAN, reassemble_sft) {
struct di_can_msg *msg;
di_can_callback_set_recv(&_ctx, recv_cb_sft_frame);
di_can_lowlevel_recv(&_ctx);
di_can_reassemble(&_ctx);
msg = di_can_recv(&_ctx, DI_CAN_MSGTYPE_RAW);
ASSERT_NE((void *)NULL, msg);
test_msg_dump(msg);
ASSERT_EQ(0x01230000, msg->canid);
ASSERT_EQ(0U, msg->size);
ASSERT_EQ((void *)NULL, msg->msg);
ASSERT_EQ(0xdeadbeef, msg->src_id);
ASSERT_EQ(0xcafebabe, msg->dst_id);
di_can_msg_free(&msg);
}
/**
* Check if MFT message is correctly reassembled
*/
static const struct di_can_frame_rx recv_cb_mft_frame_tvs[] = {
{ 0, 0, 8, 0x09e3c000, {0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff}, NULL },
{ 0, 0, 8, 0x09e3c020, {0x0f, 0x00, 0x21, 0x8d, 0x50, 0xff, 0xff, 0xff}, NULL },
{ 0, 0, 8, 0x09e3c040, {0x81, 0xa3, 0x6d, 0x73, 0x67, 0xbb, 0x48, 0x65}, NULL },
{ 0, 0, 8, 0x09e3c060, {0x6c, 0x6c, 0x6f, 0x20, 0x66, 0x72, 0x6f, 0x6d}, NULL },
{ 0, 0, 8, 0x09e3c080, {0x20, 0x44, 0x49, 0x2d, 0x4e, 0x65, 0x74, 0x20}, NULL },
{ 0, 0, 8, 0x09e3c0a0, {0x43, 0x41, 0x4e, 0x20, 0x31, 0x33, 0x33, 0x37}, NULL },
{ 0, 0, 1, 0x09e3c0c1, {0x21 }, NULL }
};
const size_t recv_cb_mft_frame_tvs_size = DI_ARRAY_SIZE(recv_cb_mft_frame_tvs);
static di_errno_t recv_cb_mft_frame(struct di_can_frame_rx *frame)
{
/* Msgtype : DI_CAN_MSGTYPE_RPC
* Transfertype : DI_CAN_TRANSFERTYPE_PUBLISH
* di_rpc_types : DI_RPC_TYPE_LOG_INFO
* Source Node ID : 0x00000000
* Destination Node ID : 0xffffffff (DI_CAN_NODEID_BROADCAST)
* Payload type : 0x0f (DI_CAN_PTYPE_MSGPACK)
* Payload size : 0x21
* Payload CRC : 0x508d
* Payload : "msg" : "Hello from DI-Net CAN 1337!"
* Extended Metadata Flags : EM_DISABLE (pre Realtime aware CAN message)
*/
static unsigned int idx = 0;
memcpy(frame, &recv_cb_mft_frame_tvs[idx], sizeof(recv_cb_mft_frame_tvs[0]));
idx++;
if (idx >= recv_cb_mft_frame_tvs_size)
idx = 0;
return DNOK;
}
TEST_F(DI_CAN, reassemble_mft) {
struct di_can_msg *msg;
di_can_callback_set_recv(&_ctx, recv_cb_mft_frame);
for (size_t n = 0; n < recv_cb_mft_frame_tvs_size; n++)
di_can_lowlevel_recv(&_ctx);
di_can_reassemble(&_ctx);
msg = di_can_recv(&_ctx, DI_CAN_MSGTYPE_RPC);
ASSERT_NE((void *)NULL, msg);
// Extended Metadata Flags field is zeroed because the EM_DISABLE is set for
// pre Realtime aware CAN-stacks.
ASSERT_EQ(0U, msg->emflags);
test_msg_dump(msg);
di_can_msg_free(&msg);
}
/**
* Check if MFT message is correctly reassembled
*/
static const struct di_can_frame_rx recv_cb_mft_rpc_frame_tvs[] = {
{ 0, 0, 8, 0x08814000, {0x47, 0x45, 0x8a, 0x51, 0xff, 0xff, 0xff, 0xff}, NULL },
{ 0, 0, 8, 0x08814020, {0x0f, 0x00, 0x4e, 0x90, 0x1d, 0xff, 0xff, 0xff}, NULL },
{ 0, 0, 8, 0x08814040, {0x91, 0x83, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xac}, NULL },
{ 0, 0, 8, 0x08814060, {0x74, 0x77, 0x73, 0x2d, 0x33, 0x30, 0x30, 0x30}, NULL },
{ 0, 0, 8, 0x08814080, {0x2d, 0x64, 0x75, 0x6d, 0xa8, 0x72, 0x65, 0x76}, NULL },
{ 0, 0, 8, 0x088140A0, {0x69, 0x73, 0x69, 0x6f, 0x6e, 0x01, 0xa7, 0x76}, NULL },
{ 0, 0, 8, 0x088140C0, {0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0xd9, 0x26}, NULL },
{ 0, 0, 8, 0x088140E0, {0x30, 0x2e, 0x33, 0x2e, 0x32, 0x2b, 0x32, 0x30}, NULL },
{ 0, 0, 8, 0x08814100, {0x31, 0x37, 0x30, 0x37, 0x31, 0x33, 0x31, 0x31}, NULL },
{ 0, 0, 8, 0x08814120, {0x32, 0x38, 0x35, 0x36, 0x2b, 0x67, 0x69, 0x74}, NULL },
{ 0, 0, 8, 0x08814140, {0x2e, 0x34, 0x36, 0x66, 0x62, 0x35, 0x61, 0x65}, NULL },
{ 0, 0, 6, 0x08814161, {0x2d, 0x64, 0x69, 0x72, 0x74, 0x79, 0x00, 0x00}, NULL },
};
const size_t recv_cb_mft_rpc_frame_tvs_size = DI_ARRAY_SIZE(recv_cb_mft_rpc_frame_tvs);
static di_errno_t recv_cb_mft_rpc_frame(struct di_can_frame_rx *frame)
{
/* Msgtype : DI_CAN_MSGTYPE_RPC
* Transfertype : DI_CAN_TRANSFERTYPE_REPLY
* di_rpc_types : DI_RPC_TYPE_DEVICE:INFO
* Source Node ID : 0x47458a51
* Destination Node ID : 0xffffffff (DI_CAN_NODEID_BROADCAST)
* Payload type : 0x0f (DI_CAN_PTYPE_MSGPACK)
* Payload size : 0x4e (78)
* Payload CRC : 0x901d
* Extended Metadata Flags : EM_DISABLE (pre Realtime aware CAN message)
*/
static unsigned int idx = 0;
memcpy(frame, &recv_cb_mft_rpc_frame_tvs[idx], sizeof(recv_cb_mft_rpc_frame_tvs[0]));
idx++;
if (idx >= recv_cb_mft_rpc_frame_tvs_size)
idx = 0;
return DNOK;
}
TEST_F(DI_CAN, reassemble_mft_rpc) {
struct di_can_msg *msg;
di_can_callback_set_recv(&_ctx, recv_cb_mft_rpc_frame);
for (size_t n = 0; n < recv_cb_mft_rpc_frame_tvs_size; n++) {
di_can_lowlevel_recv(&_ctx);
di_can_reassemble(&_ctx);
}
msg = di_can_recv(&_ctx, DI_CAN_MSGTYPE_RPC);
ASSERT_NE((void *)NULL, msg);
// Extended Metadata Flags field is zeroed because the EM_DISABLE is set for
// pre Realtime aware CAN-stacks.
ASSERT_EQ(0U, msg->emflags);
test_msg_dump(msg);
di_can_msg_free(&msg);
}