168 lines
4.7 KiB
C++
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 ) );
|
|
}
|