/** * @file tests/can_rpc.cpp * @brief brief * @date Aug 25, 2015 * @author rheijden * @copyright 2015 Dual Inventive Technology Centre B.V. * * descr */ #include #include "tests/can.h" #include #include #include #include extern "C" { #include "can.c" } static int test_send_cb_cnt = 0; TEST_CAN_INIT_DECL void test_reset_cnt(void) { test_send_cb_cnt = 0; } static std::vector g_frames_send; static di_errno_t test_can_send_cb(const struct di_can_frame_tx *frame) { struct di_can_frame_rx rx; rx.canid = frame->canid; rx.size = (uint16_t)frame->size; memcpy(rx.buf, frame->buf, rx.size); g_frames_send.push_back(rx); return DNOK; } /** Initialize send/recv callbacks */ TEST(can_send, set_callback) { di_can_callback_set_send(&can_ctx, test_can_send_cb); } /** * Test sending invalid message * 1. msg = NULL * 2. *msg = NULL * 3. (*msg)->private_data (di_can_ctx) = NULL */ TEST(can_send, invalid) { struct di_can_msg *msg = NULL; struct di_can_msg m; ASSERT_EQ(DNE_PARAM, di_can_send(NULL)); ASSERT_EQ(DNE_PARAM, di_can_send(&msg)); m.size = 0; m.size_written = 0; m.msg = NULL; m.buf = NULL; m.ctx = NULL; msg = &m; ASSERT_EQ(DNE_PARAM, di_can_send(&msg)); } /** * Send CAN message, this writes a SFT when msg->size == 0 * Check: * * src_id field is set from ctx->nodeid * * dst_id is set from msg->dst_id */ TEST(can_send, sft) { struct di_can_msg *msg; msg = di_can_msg_alloc(&can_ctx); ASSERT_NE((void *)NULL, msg); msg->canid = 0; DI_CAN_SET_DATATYPE(msg->canid, 0x123); msg->size = 0; can_ctx.nodeid = 0xdeadbeef; msg->dst_id = 0xcafebabe; di_can_send(&msg); ASSERT_EQ((void *)NULL, msg); static const struct di_can_frame_rx tvs[] = { { 0, 0, 8, 0x01230001, {0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xba, 0xbe}, NULL } }; size_t n = 0; ASSERT_EQ(DI_ARRAY_SIZE(tvs), g_frames_send.size()); for(auto f: g_frames_send) { printf(" got: "); test_can_print_frame_rx(&f); printf("expect: "); test_can_print_frame_rx(&tvs[n]); printf("\n"); ASSERT_EQ(tvs[n].canid, f.canid); EXPECT_EQ(tvs[n].size, f.size); EXPECT_EQ(0U, memcmp(tvs[n].buf, f.buf, tvs[n].size)); n++; } g_frames_send.clear(); } /** * Check if di_can_send sends the correct amount of multi-frames (MFT) * Sends a 16 byte payload (0x00 filled) * Check: * * src_id field is set from ctx->nodeid * * dst_id is set from msg->dst_id */ TEST(can_send, mft_two_payload_frames) { struct di_can_msg *msg; can_ctx.transaction = 0; msg = di_can_msg_alloc(&can_ctx); ASSERT_NE((void *)NULL, msg); msg->canid = 0; DI_CAN_SET_DATATYPE(msg->canid, 0x321); msg->size = 16; can_ctx.nodeid = 0x00001337; msg->dst_id = 0x00008888; di_buffer_flush(msg->buf); di_can_send(&msg); ASSERT_EQ((void *)NULL, msg); static const struct di_can_frame_rx tvs[] = { { 0, 0, 8, 0x03210000, {0x00, 0x00, 0x13, 0x37, 0x00, 0x00, 0x88, 0x88}, NULL }, // Source/Destination Node ID { 0, 0, 8, 0x03210020, {0x00, 0x00, 0x10, 0x6a, 0x0a, 0xff, 0xff, 0xff}, NULL }, // MFT metadata frame (ptype, psize, pcrc) { 0, 0, 8, 0x03210040, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, NULL }, // Transfer Payload Data frame 1 { 0, 0, 8, 0x03210061, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, NULL }, // Transfer Payload Data frame 2 }; size_t n = 0; ASSERT_EQ(DI_ARRAY_SIZE(tvs), g_frames_send.size()); for(auto f: g_frames_send) { printf(" got: "); test_can_print_frame_rx(&f); printf("expect: "); test_can_print_frame_rx(&tvs[n]); printf("\n"); ASSERT_EQ(tvs[n].canid, f.canid); EXPECT_EQ(tvs[n].size, f.size); EXPECT_EQ(0U, memcmp(tvs[n].buf, f.buf, tvs[n].size)); n++; } g_frames_send.clear(); } /** * Send CAN message, this writes a SFT when msg->size == 0 * Check: * * src_id field is set from ctx->nodeid * * dst_id is DI_CAN_NODEID_BROADCAST when msg->broadcast = true */ TEST(can_send, sft_broadcast) { struct di_can_msg *msg; can_ctx.transaction = 0; msg = di_can_msg_alloc(&can_ctx); ASSERT_NE((void *)NULL, msg); msg->canid = 0; DI_CAN_SET_DATATYPE(msg->canid, 0x123); msg->size = 0; can_ctx.nodeid = 0xdeadbeef; msg->broadcast = true; di_can_send(&msg); ASSERT_EQ((void *)NULL, msg); static const struct di_can_frame_rx tvs[] = { { 0, 0, 8, 0x01230001, {0xde, 0xad, 0xbe, 0xef, 0xff, 0xff, 0xff, 0xff}, NULL } }; size_t n = 0; ASSERT_EQ(DI_ARRAY_SIZE(tvs), g_frames_send.size()); for(auto f: g_frames_send) { printf(" got: "); test_can_print_frame_rx(&f); printf("expect: "); test_can_print_frame_rx(&tvs[n]); printf("\n"); ASSERT_EQ(tvs[n].canid, f.canid); EXPECT_EQ(tvs[n].size, f.size); EXPECT_EQ(0U, memcmp(tvs[n].buf, f.buf, tvs[n].size)); n++; } g_frames_send.clear(); }