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

207 lines
4.8 KiB
C++

/**
* @file tests/can_rpc.cpp
* @brief brief
* @date Aug 25, 2015
* @author rheijden
* @copyright 2015 Dual Inventive Technology Centre B.V.
*
* descr
*/
#include <cstdio>
#include "tests/can.h"
#include <di/can.h>
#include <di/can/frame.h>
#include <gtest/gtest.h>
#include <vector>
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<struct di_can_frame_rx> 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, 0x00, 0x00, 0x00}, 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->dst_id = DI_CAN_NODEID_BROADCAST;
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();
}