/** * @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 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); }