mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
tests: add test application for netdev2_test
This commit is contained in:
parent
97de8aa52b
commit
076a49b512
17
tests/netdev2_test/Makefile
Normal file
17
tests/netdev2_test/Makefile
Normal file
@ -0,0 +1,17 @@
|
||||
APPLICATION = netdev2_test
|
||||
include ../Makefile.tests_common
|
||||
|
||||
DISABLE_MODULE = auto_init
|
||||
|
||||
FEATURES_REQUIRED += periph_timer # xtimer required for this application
|
||||
|
||||
USEMODULE += gnrc
|
||||
USEMODULE += gnrc_neterr
|
||||
USEMODULE += gnrc_netif
|
||||
USEMODULE += gnrc_netdev2
|
||||
USEMODULE += netdev2_test
|
||||
USEMODULE += od
|
||||
|
||||
CFLAGS += -DGNRC_PKTBUF_SIZE=200
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
359
tests/netdev2_test/main.c
Normal file
359
tests/netdev2_test/main.c
Normal file
@ -0,0 +1,359 @@
|
||||
/*
|
||||
* 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) \
|
||||
puts("Executing " # test "()"); \
|
||||
if (!test()) { \
|
||||
puts(" + failed."); \
|
||||
return 1; \
|
||||
} \
|
||||
else { \
|
||||
puts(" + succeeded."); \
|
||||
}
|
||||
|
||||
static 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, void *info);
|
||||
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);
|
||||
static int _dev_set_addr(netdev2_t *dev, void *value, size_t max_len);
|
||||
|
||||
/* tests getter */
|
||||
static 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 */
|
||||
static 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 */
|
||||
static 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;
|
||||
}
|
||||
|
||||
static int test_set_addr(void)
|
||||
{
|
||||
static const uint8_t new_addr[] = { 0x71, 0x29, 0x5b, 0xc8, 0x52, 0x65 };
|
||||
uint8_t tmp[sizeof(new_addr)];
|
||||
|
||||
if (gnrc_netapi_set(_mac_pid, NETOPT_ADDRESS, 0, (void *)new_addr,
|
||||
sizeof(new_addr)) != sizeof(new_addr)) {
|
||||
puts("Error setting device address");
|
||||
return 0;
|
||||
}
|
||||
if (gnrc_netapi_get(_mac_pid, NETOPT_ADDRESS, 0, tmp,
|
||||
sizeof(tmp)) != sizeof(tmp)) {
|
||||
puts("Error setting device address");
|
||||
return 0;
|
||||
}
|
||||
else if (memcmp(tmp, new_addr, sizeof(new_addr)) != 0) {
|
||||
puts("Set to wrong device address");
|
||||
return 0;
|
||||
}
|
||||
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);
|
||||
netdev2_test_set_set_cb(&_dev, NETOPT_ADDRESS, _dev_set_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);
|
||||
EXECUTE(test_set_addr);
|
||||
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 *info)
|
||||
{
|
||||
(void)dev;
|
||||
(void)info;
|
||||
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);
|
||||
}
|
||||
|
||||
static int _dev_set_addr(netdev2_t *dev, void *value, size_t value_len)
|
||||
{
|
||||
(void)dev;
|
||||
if (value_len != sizeof(_dev_addr)) {
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
memcpy(_dev_addr, value, sizeof(_dev_addr));
|
||||
return sizeof(_dev_addr);
|
||||
}
|
Loading…
Reference in New Issue
Block a user