src.dualinventive.com/fw/dncm/libdi/tests/drv_hl854x_udp.cpp

168 lines
4.7 KiB
C++

#include <string>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <gtest/gtest.h>
#include <di/drv/hl854x.h>
extern "C" {
#include "drv/hl854x/udp.c"
}
using namespace std;
struct test_drv_hl854x_readwrite_cb_items {
size_t n;
const char **tv;
size_t tvlen;
string writebuf;
};
static struct test_drv_hl854x_readwrite_cb_items g_tvs;
size_t test_drv_hl854x_read_cb(void *buf, size_t nbyte)
{
const size_t len = strlen(g_tvs.tv[g_tvs.n]);
const char *str = g_tvs.tv[g_tvs.n];
if (nbyte < len)
return 0;
memcpy(buf, str, nbyte);
g_tvs.n++;
if (g_tvs.n == g_tvs.tvlen)
g_tvs.n = 0;
return len;
}
size_t test_drv_hl854x_write_cb(const void *buf, size_t nbyte)
{
g_tvs.writebuf.append(static_cast<const char *>(buf), nbyte);
return nbyte;
}
/**
* Initialize an test string for reading (and set the correct UDP sessions states)
* @param ctx Modem context (uinitialized)
* @param str Mocked modem string readable by the driver
*/
void test_hl854x_udp_init(struct di_drv_hl854x_ctx *ctx, const char **tv, const size_t tvlen)
{
di_drv_hl854x_init(ctx);
// The reader is default initialized as locked for the unit tests we must be able to
// read synchronous. In the real world there is an async reader so we dont miss any
// data.
di_bsem_post(&ctx->lock.reader);
di_drv_hl854x_set_read(ctx, test_drv_hl854x_read_cb);
di_drv_hl854x_set_write(ctx, test_drv_hl854x_write_cb);
g_tvs.n = 0;
g_tvs.tv = tv;
g_tvs.tvlen = tvlen;
g_tvs.writebuf.clear();
ctx->carrier.status = HL854X_CARRIER_STATUS_REG_HOME;
ctx->udp.session_id = HL854X_SESSION_ID_MIN;
ctx->udp.state = HL854X_UDP_STATE_READY;
}
/**
* Verify the initialisation is correct of the UDP session
*/
TEST(drv_hl854x_udp, init) {
struct di_drv_hl854x_ctx ctx;
di_drv_hl854x_init(&ctx);
ASSERT_EQ(HL854X_SESSION_ID_UNKNOWN, ctx.udp.session_id);
ASSERT_EQ(HL854X_UDP_STATE_UNKNOWN, ctx.udp.state);
ASSERT_EQ(nullptr, ctx.udp.remote_addr);
ASSERT_EQ(nullptr, ctx.udp.remote_port);
}
/**
* Test the sending mechanism
* * AT+KUDPSND=...
* * Wait for modem `CONNECT\r\n` reply
* * Write data bytes
* * Wait for modem `OK` reply
*/
TEST(drv_hl854x_udp, send) {
static const char *addr = "10.0.0.1";
static const char *port = "4000";
static const char *data = "hello world!";
static const char *tv[2] = {"CONNECT\r\n", "OK\r\n"};
struct di_drv_hl854x_ctx ctx;
test_hl854x_udp_init(&ctx, tv, 2);
di_drv_hl854x_udp_set_remote_endpoint(&ctx, addr, port);
ASSERT_EQ(addr, ctx.udp.remote_addr);
ASSERT_EQ(port, ctx.udp.remote_port);
ASSERT_EQ(DNOK, di_drv_hl854x_udp_send(&ctx, data, strlen(data)));
ASSERT_EQ(61, g_tvs.writebuf.size());
ASSERT_TRUE(nullptr != strstr(g_tvs.writebuf.c_str(), "AT+KUDPSND=1,\"10.0.0.1\",4000,12\r\n"));
ASSERT_TRUE(nullptr != strstr(g_tvs.writebuf.c_str(), "hello world!"));
}
/**
* Verify if the recv_wait_ndata_available works as expected when an async URC KUDP_DATA is send
* * Test DNE_TIMEOUT on 1ms
* * Recv 12 bytes KUDP_DATA URC
* * Test DNOK on 1ms
* * Check ndata_available is 12 bytes
*/
TEST(drv_hl854x_udp, recv_wait_ndata_available) {
size_t ndata_available = 0;
struct di_drv_hl854x_ctx ctx;
static const char *tv[1] = {"+KUDP_DATA: 1,12\r\n"};
test_hl854x_udp_init(&ctx, tv, 1);
// Check the mutex works and has a timeout because there are not data bytes available
ASSERT_EQ(DNE_TIMEOUT, di_drv_hl854x_udp_recv_wait_ndata_available(&ctx, 1, &ndata_available));
ASSERT_EQ(ndata_available, 0);
// Send URC for session 1 with 12 bytes ready
di_drv_hl854x_read(&ctx);
ASSERT_EQ(ctx.udp.ndata_available, 12);
// Read amount of data bytes available
ASSERT_EQ(DNOK, di_drv_hl854x_udp_recv_wait_ndata_available(&ctx, 1, &ndata_available));
// Check application has read the correct amount of bytes available and udp session
// is reset to zero
ASSERT_EQ(ndata_available, 12);
ASSERT_EQ(ctx.udp.ndata_available, 0);
}
/**
* Test the receive mechanism
*/
TEST(drv_hl854x_udp, recv) {
size_t ndata_available = 0;
uint8_t recv_buf[256];
static const char *tv[] = {"+KUDP_DATA: 1,8\r\n", "CONNECT\r\n", "TESTDATA--EOF--Pattern--\r\n", "OK\r\n"};
struct di_drv_hl854x_ctx ctx;
memset(recv_buf, 0, sizeof(recv_buf));
test_hl854x_udp_init(&ctx, tv, DI_ARRAY_SIZE(tv));
// Send URC for session 1 with 8 bytes ready
di_drv_hl854x_read(&ctx);
ASSERT_EQ(8, ctx.udp.ndata_available);
// Read amount of data bytes available
ASSERT_EQ(DNOK, di_drv_hl854x_udp_recv_wait_ndata_available(&ctx, HL854X_TIMEOUT_INFINITE, &ndata_available));
// Check application has read the correct amount of bytes available and udp session
ASSERT_EQ(8, ndata_available);
ASSERT_EQ(8U, di_drv_hl854x_udp_recv(&ctx, recv_buf, sizeof(recv_buf)));
EXPECT_TRUE( 0 == memcmp( "TESTDATA", recv_buf, 8 ) );
}