Skip to content

Commit

Permalink
tests: add test application for netdev2_test
Browse files Browse the repository at this point in the history
  • Loading branch information
miri64 committed Feb 24, 2016
1 parent 97829ed commit b04f4c0
Show file tree
Hide file tree
Showing 2 changed files with 334 additions and 0 deletions.
15 changes: 15 additions & 0 deletions tests/netdev2_test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
APPLICATION = netdev2_test
include ../Makefile.tests_common

DISABLE_MODULE = auto_init

USEMODULE += gnrc
USEMODULE += gnrc_neterr
USEMODULE += gnrc_netif
USEMODULE += gnrc_netdev2
USEMODULE += netdev2_test
USEMODULE += od

CFLAGS += -DGNRC_PKTBUF_SIZE=100

include $(RIOTBASE)/Makefile.include
319 changes: 319 additions & 0 deletions tests/netdev2_test/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,319 @@
/*
* Copyright (C) 2016 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @{
*
* @file
* @brief Show case application for netdev2_test
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*
* @}
*/

#include <stdio.h>

#include "msg.h"
#include "net/ethernet.h"
#include "net/gnrc.h"
#include "net/gnrc/netdev2/eth.h"
#include "net/netdev2_test.h"
#include "od.h"
#include "thread.h"
#include "utlist.h"

#define _EXP_LENGTH (64)

#define _MAC_STACKSIZE (THREAD_STACKSIZE_DEFAULT + THREAD_EXTRA_STACKSIZE_PRINTF)
#define _MAC_PRIO (THREAD_PRIORITY_MAIN - 4)

#define _MAIN_MSG_QUEUE_SIZE (2)

#define _TEST_PAYLOAD1 "gO3Xt,fP)6* MR161Auk?W^mTb\"LmY^Qc5w1h:C<+n(*/@4k("
#define _TEST_PAYLOAD2 "*b/'XKkraEBexaU\\O-X&<Bl'n%35Ll+nDy,jQ+[Oe4:9( 4cI"

#define EXECUTE(test) \
if (!test()) { \
puts(# test " failed."); \
return 1; \
}

static const uint8_t _dev_addr[] = { 0x6c, 0x5d, 0xff, 0x73, 0x84, 0x6f };
static const uint8_t _test_dst[] = { 0xf5, 0x19, 0x9a, 0x1d, 0xd8, 0x8f };
static const uint8_t _test_src[] = { 0x41, 0x9b, 0x9f, 0x56, 0x36, 0x46 };

static char _mac_stack[_MAC_STACKSIZE];
static gnrc_netdev2_t _gnrc_dev;
static netdev2_test_t _dev;
static msg_t _main_msg_queue[_MAIN_MSG_QUEUE_SIZE];
static uint8_t _tmp[_EXP_LENGTH];
static kernel_pid_t _mac_pid;
static uint8_t _tmp_len = 0;

static void _dev_isr(netdev2_t *dev);
static int _dev_recv(netdev2_t *dev, char *buf, int len);
static int _dev_send(netdev2_t *dev, const struct iovec *vector, int count);
static int _dev_get_addr(netdev2_t *dev, void *value, size_t max_len);

/* tests getter */
int test_get_addr(void)
{
uint8_t tmp[sizeof(_dev_addr)];

if (gnrc_netapi_get(_mac_pid, NETOPT_ADDRESS, 0, tmp, sizeof(tmp)) != sizeof(_dev_addr)) {
puts("Error getting device address");
return 0;
}
else if (memcmp(tmp, _dev_addr, sizeof(_dev_addr)) != 0) {
puts("Got wrong device address");
return 0;
}
return 1;
}

/* tests sending */
int test_send(void)
{
ethernet_hdr_t *exp_mac = (ethernet_hdr_t *)_tmp;
uint8_t *exp_payload = _tmp + sizeof(ethernet_hdr_t);
gnrc_pktsnip_t *pkt, *hdr;
msg_t msg;

/* prepare packet for sending */
pkt = gnrc_pktbuf_add(NULL, _TEST_PAYLOAD1, sizeof(_TEST_PAYLOAD1) - 1,
GNRC_NETTYPE_UNDEF);
if (pkt == NULL) {
puts("Could not allocate send payload");
return 0;
}
hdr = gnrc_netif_hdr_build(NULL, 0, (uint8_t *)_test_dst, sizeof(_test_dst));
if (hdr == NULL) {
gnrc_pktbuf_release(pkt);
puts("Could not allocate send header");
return 0;
}
LL_PREPEND(pkt, hdr);
/* prepare expected data */
memcpy(exp_mac->dst, _test_dst, sizeof(_test_dst));
memcpy(exp_mac->src, _dev_addr, sizeof(_dev_addr));
exp_mac->type = byteorder_htons(ETHERTYPE_UNKNOWN);
memcpy(exp_payload, _TEST_PAYLOAD1, sizeof(_TEST_PAYLOAD1) - 1);
_tmp_len = sizeof(_TEST_PAYLOAD1) + sizeof(ethernet_hdr_t) - 1;
/* register for returned packet status */
if (gnrc_neterr_reg(pkt) != 0) {
puts("Can not register for error reporting");
return 0;
}
/* send packet to MAC layer */
gnrc_netapi_send(_mac_pid, pkt);
/* wait for packet status and check */
msg_receive(&msg);
if ((msg.type != GNRC_NETERR_MSG_TYPE) ||
(msg.content.value != GNRC_NETERR_SUCCESS)) {
puts("Error sending packet");
return 0;
}
return 1;
}

/* tests receiving */
int test_receive(void)
{
ethernet_hdr_t *rcv_mac = (ethernet_hdr_t *)_tmp;
uint8_t *rcv_payload = _tmp + sizeof(ethernet_hdr_t);
gnrc_pktsnip_t *pkt, *hdr;
gnrc_netreg_entry_t me = { NULL, GNRC_NETREG_DEMUX_CTX_ALL,
thread_getpid() };
msg_t msg;

if (_dev.netdev.event_callback == NULL) {
puts("Device's event_callback not set");
return 0;
}
/* prepare receive buffer */
memcpy(rcv_mac->dst, _dev_addr, sizeof(_dev_addr));
memcpy(rcv_mac->src, _test_src, sizeof(_test_src));
/* no gnrc_ipv6 in compile unit => ETHERTYPE_IPV6 translates to
* GNRC_NETTYPE_UNDEF */
rcv_mac->type = byteorder_htons(ETHERTYPE_IPV6);
memcpy(rcv_payload, _TEST_PAYLOAD2, sizeof(_TEST_PAYLOAD2) - 1);
_tmp_len = sizeof(_TEST_PAYLOAD2) + sizeof(ethernet_hdr_t) - 1;

/* register for GNRC_NETTYPE_UNDEF */
gnrc_netreg_register(GNRC_NETTYPE_UNDEF, &me);
/* fire ISR event */
_dev.netdev.event_callback((netdev2_t *)&_dev.netdev, NETDEV2_EVENT_ISR,
&_dev.netdev.isr_arg);
/* wait for packet from MAC layer*/
msg_receive(&msg);
/* check message */
if (msg.sender_pid != _mac_pid) {
puts("Unexpected sender of netapi receive message");
return 0;
}
if (msg.type != GNRC_NETAPI_MSG_TYPE_RCV) {
puts("Expected netapi receive message");
return 0;
}
pkt = (gnrc_pktsnip_t *)msg.content.ptr;
/* check payload */
if (pkt->size != _tmp_len - sizeof(ethernet_hdr_t)) {
puts("Payload of unexpected size");
}
if ((pkt->type != GNRC_NETTYPE_UNDEF) ||
(memcmp(pkt->data, _TEST_PAYLOAD2, pkt->size) != 0)) {
puts("Unexpected payload");
puts("===========================================================");
puts("expected");
puts("===========================================================");
od_hex_dump(_TEST_PAYLOAD2, pkt->size, OD_WIDTH_DEFAULT);
puts("===========================================================");
puts("send data");
puts("===========================================================");
od_hex_dump(pkt->data, pkt->size, OD_WIDTH_DEFAULT);
return 0;
}
hdr = pkt->next;
/* check netif header */
if ((hdr->type != GNRC_NETTYPE_NETIF) || (hdr->next != NULL) ||
(hdr->size) != (sizeof(gnrc_netif_hdr_t) + (2 * ETHERNET_ADDR_LEN))) {
puts("Malformed header received");
return 0;
}
if (memcmp(gnrc_netif_hdr_get_src_addr(hdr->data), _test_src,
ETHERNET_ADDR_LEN) != 0) {
char addr_str[ETHERNET_ADDR_LEN * 3];
puts("Unexpected source received");
puts("=================");
puts("expected");
puts("=================");
puts(gnrc_netif_addr_to_str(addr_str, sizeof(addr_str),
_test_src,
ETHERNET_ADDR_LEN));
puts("=================");
puts("received source");
puts("=================");
puts(gnrc_netif_addr_to_str(addr_str, sizeof(addr_str),
gnrc_netif_hdr_get_src_addr(hdr->data),
ETHERNET_ADDR_LEN));
return 0;
}
if (memcmp(gnrc_netif_hdr_get_dst_addr(hdr->data), _dev_addr,
ETHERNET_ADDR_LEN) != 0) {
char addr_str[ETHERNET_ADDR_LEN * 3];
puts("Unexpected destination received");
puts("=================");
puts("expected");
puts("=================");
puts(gnrc_netif_addr_to_str(addr_str, sizeof(addr_str),
_dev_addr,
ETHERNET_ADDR_LEN));
puts("====================");
puts("received destination");
puts("====================");
puts(gnrc_netif_addr_to_str(addr_str, sizeof(addr_str),
gnrc_netif_hdr_get_dst_addr(hdr->data),
ETHERNET_ADDR_LEN));
return 0;
}

gnrc_pktbuf_release(pkt);
gnrc_netreg_unregister(GNRC_NETTYPE_UNDEF, &me);
return 1;
}

int main(void)
{
/* initialization */
gnrc_pktbuf_init();
msg_init_queue(_main_msg_queue, _MAIN_MSG_QUEUE_SIZE);
netdev2_test_setup(&_dev, NULL);
netdev2_test_set_isr_cb(&_dev, _dev_isr);
netdev2_test_set_recv_cb(&_dev, _dev_recv);
netdev2_test_set_send_cb(&_dev, _dev_send);
netdev2_test_set_get_cb(&_dev, NETOPT_ADDRESS, _dev_get_addr);
gnrc_netdev2_eth_init(&_gnrc_dev, (netdev2_t *)(&_dev));
_mac_pid = gnrc_netdev2_init(_mac_stack, _MAC_STACKSIZE, _MAC_PRIO,
"gnrc_netdev_eth_test", &_gnrc_dev);
if (_mac_pid <= KERNEL_PID_UNDEF) {
puts("Could not start MAC thread\n");
return 1;
}

/* test execution */
EXECUTE(test_get_addr);
EXECUTE(test_send);
EXECUTE(test_receive);
puts("ALL TESTS SUCCESSFUL");

return 0;
}

/* netdev2_test callbacks */
static void _dev_isr(netdev2_t *dev)
{
(void)dev;
if (dev->event_callback) {
dev->event_callback(dev, NETDEV2_EVENT_RX_COMPLETE, dev->isr_arg);
}
}

static int _dev_recv(netdev2_t *dev, char *buf, int len)
{
(void)dev;
if (buf == NULL) {
return _tmp_len;
}
else if (len < _tmp_len) {
return -ENOBUFS;
}
else {
memcpy(buf, _tmp, _tmp_len);
return _tmp_len;
}
}

static int _dev_send(netdev2_t *dev, const struct iovec *vector, int count)
{
int idx = 0;

(void)dev;
/* check packet content with expected data */
for (int i = 0; i < count; i++) {
if (memcmp(&(_tmp[idx]), vector[i].iov_base, vector[i].iov_len) != 0) {
printf("Unexpected send data (vector index = %d)\n", i);
puts("===========================================================");
puts("expected");
puts("===========================================================");
od_hex_dump(&_tmp[idx], vector[i].iov_len, OD_WIDTH_DEFAULT);
puts("===========================================================");
puts("send data");
puts("===========================================================");
od_hex_dump(vector[i].iov_base, vector[i].iov_len, OD_WIDTH_DEFAULT);
return -EINVAL;
}
idx += vector[i].iov_len;
}
if (idx != _tmp_len) {
printf("Unexpected send length: %d (expected: %d)\n", idx, _tmp_len);
return -EINVAL;
}

return idx;
}

static int _dev_get_addr(netdev2_t *dev, void *value, size_t max_len)
{
(void)dev;
if (max_len < sizeof(_dev_addr)) {
return -ENOBUFS;
}
memcpy(value, _dev_addr, sizeof(_dev_addr));
return sizeof(_dev_addr);
}

0 comments on commit b04f4c0

Please sign in to comment.