/** * @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 #include 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 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!" */ static unsigned int idx = 0; static const struct di_can_frame_rx 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 } }; memcpy(frame, &tvs[idx], sizeof(tvs[0])); idx++; if (idx >= DI_ARRAY_SIZE(tvs)) 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 < 7; n++) di_can_lowlevel_recv(&_ctx); di_can_reassemble(&_ctx); msg = di_can_recv(&_ctx, DI_CAN_MSGTYPE_RPC); ASSERT_NE((void *)NULL, msg); test_msg_dump(msg); di_can_msg_free(&msg); }