mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
1086 lines
29 KiB
C
1086 lines
29 KiB
C
/*
|
|
* Copyright (C) 2014 Martine Lenders <mlenders@inf.fu-berlin.de>
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
/**
|
|
* @ingroup tests
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief Tests for general network device interface
|
|
*
|
|
*
|
|
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
|
*
|
|
* @}
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <inttypes.h>
|
|
|
|
#ifdef MODULE_NATIVENET
|
|
#include "nativenet.h"
|
|
#endif
|
|
|
|
#include "net_help.h"
|
|
#include "netdev/base.h"
|
|
#include "netdev/default.h"
|
|
|
|
#ifdef NETDEV_DEFAULT
|
|
#define SHELL_BUFSIZE (UART0_BUFSIZE)
|
|
|
|
static size_t dev_address_len = 0;
|
|
static netdev_t *dev = NULL;
|
|
|
|
/***********************************
|
|
* helper functions *
|
|
***********************************/
|
|
static inline int _got_uint8_value(char *param_name, uint8_t *value_ptr, size_t value_len,
|
|
uint8_t check_value, uint8_t value_exp)
|
|
{
|
|
printf("Got %s of value %" PRIu8 " of length %zu\n", param_name, *value_ptr, value_len);
|
|
|
|
if (check_value) {
|
|
return (*value_ptr == value_exp) ? 1 : 0;
|
|
}
|
|
else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
static inline int _got_uint16_value(char *param_name, uint16_t *value_ptr, size_t value_len,
|
|
uint8_t check_value, uint16_t value_exp)
|
|
{
|
|
printf("Got %s of value %" PRIu16 " of length %zu\n", param_name, *value_ptr, value_len);
|
|
|
|
if (check_value) {
|
|
return (*value_ptr == value_exp) ? 1 : 0;
|
|
}
|
|
else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
static inline int _got_uint32_value(char *param_name, uint32_t *value_ptr, size_t value_len,
|
|
uint8_t check_value, uint32_t value_exp)
|
|
{
|
|
printf("Got %s of value %" PRIu32 " of length %zu\n", param_name, *value_ptr, value_len);
|
|
|
|
if (check_value) {
|
|
return (*value_ptr == value_exp) ? 1 : 0;
|
|
}
|
|
else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
static inline int _got_uint64_value(char *param_name, uint64_t *value_ptr, size_t value_len,
|
|
uint8_t check_value, uint64_t value_exp)
|
|
{
|
|
printf("Got %s of value %" PRIu64 " of length %zu\n", param_name, *value_ptr, value_len);
|
|
|
|
if (check_value) {
|
|
return (*value_ptr == value_exp) ? 1 : 0;
|
|
}
|
|
else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/***********************************
|
|
* test channel *
|
|
***********************************/
|
|
static int init_channel(void)
|
|
{
|
|
uint8_t channel = NETDEV_TEST_CHANNEL;
|
|
int res = dev->driver->set_option(dev, NETDEV_OPT_CHANNEL,
|
|
&channel, sizeof(uint8_t));
|
|
|
|
switch (res) {
|
|
case 0:
|
|
printf("Channel was set to %" PRIu8 "\n", channel);
|
|
return 1;
|
|
|
|
case -EINVAL:
|
|
printf("Channel %" PRIu8 " not supported\n", channel);
|
|
break;
|
|
|
|
case -ENODEV:
|
|
puts("Device was not initialized");
|
|
break;
|
|
|
|
case -ENOTSUP:
|
|
puts("Does not support setting the channel");
|
|
return 2;
|
|
|
|
case -EOVERFLOW:
|
|
puts("1 byte overflows o_o?!!?");
|
|
break;
|
|
|
|
default:
|
|
puts("unknown error");
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int check_channel(void)
|
|
{
|
|
uint8_t channel[sizeof(uint64_t)];
|
|
size_t channel_len = sizeof(uint64_t);
|
|
int res = dev->driver->get_option(dev, NETDEV_OPT_CHANNEL,
|
|
&channel, &channel_len);
|
|
|
|
switch (res) {
|
|
case 0:
|
|
switch (channel_len) {
|
|
case 1:
|
|
return _got_uint8_value("channel", (uint8_t *)channel, channel_len, 1, NETDEV_TEST_CHANNEL);
|
|
|
|
case 2:
|
|
return _got_uint16_value("channel", (uint16_t *)channel, channel_len, 1, NETDEV_TEST_CHANNEL);
|
|
|
|
case 4:
|
|
return _got_uint32_value("channel", (uint32_t *)channel, channel_len, 1, NETDEV_TEST_CHANNEL);
|
|
|
|
case 8:
|
|
return _got_uint64_value("channel", (uint64_t *)channel, channel_len, 1, NETDEV_TEST_CHANNEL);
|
|
|
|
default:
|
|
printf("Unexpected channel type of length %u:", channel_len);
|
|
|
|
for (size_t i = 0; i < channel_len; i++) {
|
|
printf(" %02x", channel[i]);
|
|
}
|
|
|
|
printf("\n");
|
|
return 0;
|
|
}
|
|
|
|
case -ENODEV:
|
|
puts("Device was not initialized");
|
|
break;
|
|
|
|
case -ENOTSUP:
|
|
puts("Does not support getting of channel");
|
|
return 2;
|
|
|
|
case -EOVERFLOW:
|
|
puts("Channel type bigger then 64 bit.");
|
|
break;
|
|
|
|
default:
|
|
puts("unknown error");
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***********************************
|
|
* test address *
|
|
***********************************/
|
|
static int init_address(void)
|
|
{
|
|
uint8_t address = NETDEV_TEST_ADDRESS;
|
|
int res = dev->driver->set_option(dev, NETDEV_OPT_ADDRESS,
|
|
&address, sizeof(uint8_t));
|
|
|
|
switch (res) {
|
|
case 0:
|
|
printf("Address was set to %" PRIu8 "\n", address);
|
|
return 1;
|
|
|
|
case -EINVAL:
|
|
printf("Address %" PRIu8 " not supported\n", address);
|
|
break;
|
|
|
|
case -ENODEV:
|
|
puts("Device was not initialized");
|
|
break;
|
|
|
|
case -ENOTSUP:
|
|
puts("Does not support setting the address");
|
|
return 2;
|
|
|
|
case -EOVERFLOW:
|
|
puts("1 byte overflows o_o?!!?");
|
|
break;
|
|
|
|
default:
|
|
puts("unknown error");
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int check_address(void)
|
|
{
|
|
uint8_t address[sizeof(uint64_t)];
|
|
size_t address_len = sizeof(uint64_t);
|
|
int res = dev->driver->get_option(dev, NETDEV_OPT_ADDRESS,
|
|
&address, &address_len);
|
|
|
|
switch (res) {
|
|
case 0:
|
|
dev_address_len = address_len;
|
|
|
|
switch (address_len) {
|
|
case 1:
|
|
return _got_uint8_value("address", (uint8_t *)address, address_len, 1, NETDEV_TEST_ADDRESS);
|
|
|
|
case 2:
|
|
return _got_uint16_value("address", (uint16_t *)address, address_len, 1, NETDEV_TEST_ADDRESS);
|
|
|
|
case 4:
|
|
return _got_uint32_value("address", (uint32_t *)address, address_len, 1, NETDEV_TEST_ADDRESS);
|
|
|
|
case 6:
|
|
printf("Got address of length %u of value: ", address_len);
|
|
|
|
for (size_t i = 0; i < address_len; i++) {
|
|
printf(" %02x", address[i]);
|
|
}
|
|
|
|
printf("\n");
|
|
return 1;
|
|
|
|
case 8:
|
|
return _got_uint64_value("address", (uint64_t *)address, address_len, 1, NETDEV_TEST_ADDRESS);
|
|
|
|
default:
|
|
printf("Unexpected address type of length %u:", address_len);
|
|
|
|
for (size_t i = 0; i < address_len; i++) {
|
|
printf(" %02x", address[i]);
|
|
}
|
|
|
|
printf("\n");
|
|
return 0;
|
|
}
|
|
|
|
case -ENODEV:
|
|
puts("Device was not initialized");
|
|
break;
|
|
|
|
case -ENOTSUP:
|
|
puts("Does not support getting the address");
|
|
return 2;
|
|
|
|
case -EOVERFLOW:
|
|
puts("Address type bigger then 64 bit.");
|
|
break;
|
|
|
|
default:
|
|
puts("unknown error");
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***********************************
|
|
* test long address *
|
|
***********************************/
|
|
static int init_long_address(void)
|
|
{
|
|
uint8_t address = NETDEV_TEST_ADDRESS;
|
|
int res = dev->driver->set_option(dev, NETDEV_OPT_ADDRESS_LONG,
|
|
&address, sizeof(uint8_t));
|
|
|
|
switch (res) {
|
|
case 0:
|
|
printf("Long address was set to %" PRIu8 "\n", address);
|
|
return 1;
|
|
|
|
case -EINVAL:
|
|
printf("Long address %" PRIu8 " not supported\n", address);
|
|
break;
|
|
|
|
case -ENODEV:
|
|
puts("Device was not initialized");
|
|
break;
|
|
|
|
case -ENOTSUP:
|
|
puts("Does not support setting the long address");
|
|
return 2;
|
|
|
|
case -EOVERFLOW:
|
|
puts("1 byte overflows o_o?!!?");
|
|
break;
|
|
|
|
default:
|
|
puts("unknown error");
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int check_long_address(void)
|
|
{
|
|
uint8_t address[sizeof(uint64_t)];
|
|
size_t address_len = sizeof(uint64_t);
|
|
int res = dev->driver->get_option(dev, NETDEV_OPT_ADDRESS_LONG,
|
|
&address, &address_len);
|
|
|
|
switch (res) {
|
|
case 0:
|
|
switch (address_len) {
|
|
case 1:
|
|
return _got_uint8_value("long address", (uint8_t *)address, address_len, 1, NETDEV_TEST_ADDRESS);
|
|
|
|
case 2:
|
|
return _got_uint16_value("long address", (uint16_t *)address, address_len, 1, NETDEV_TEST_ADDRESS);
|
|
|
|
case 4:
|
|
return _got_uint32_value("long address", (uint32_t *)address, address_len, 1, NETDEV_TEST_ADDRESS);
|
|
|
|
case 6:
|
|
printf("Got long address of length %u of value: ", address_len);
|
|
|
|
for (size_t i = 0; i < address_len; i++) {
|
|
printf(" %02x", address[i]);
|
|
}
|
|
|
|
printf("\n");
|
|
return 1;
|
|
|
|
case 8:
|
|
return _got_uint64_value("long address", (uint64_t *)address, address_len, 1, NETDEV_TEST_ADDRESS);
|
|
|
|
default:
|
|
printf("Unexpected long address type of length %u:", address_len);
|
|
|
|
for (size_t i = 0; i < address_len; i++) {
|
|
printf(" %02x", address[i]);
|
|
}
|
|
|
|
printf("\n");
|
|
return 0;
|
|
}
|
|
|
|
case -ENODEV:
|
|
puts("Device was not initialized");
|
|
break;
|
|
|
|
case -ENOTSUP:
|
|
puts("Does not support getting the long address");
|
|
return 2;
|
|
|
|
case -EOVERFLOW:
|
|
puts("Long address type bigger then 64 bit.");
|
|
break;
|
|
|
|
default:
|
|
puts("unknown error");
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***********************************
|
|
* test network ID *
|
|
***********************************/
|
|
static int init_nid(void)
|
|
{
|
|
uint8_t nid = NETDEV_TEST_NID;
|
|
int res = dev->driver->set_option(dev, NETDEV_OPT_NID,
|
|
&nid, sizeof(uint8_t));
|
|
|
|
switch (res) {
|
|
case 0:
|
|
printf("Network ID was set to %" PRIu8 "\n", nid);
|
|
return 1;
|
|
|
|
case -EINVAL:
|
|
printf("Network ID %" PRIu8 " not supported\n", nid);
|
|
break;
|
|
|
|
case -ENODEV:
|
|
puts("Device was not initialized");
|
|
break;
|
|
|
|
case -ENOTSUP:
|
|
puts("Does not support setting the network ID");
|
|
return 2;
|
|
|
|
case -EOVERFLOW:
|
|
puts("1 byte overflows o_o?!!?");
|
|
break;
|
|
|
|
default:
|
|
puts("unknown error");
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int check_nid(void)
|
|
{
|
|
uint8_t nid[sizeof(uint64_t)];
|
|
size_t nid_len = sizeof(uint64_t);
|
|
int res = dev->driver->get_option(dev, NETDEV_OPT_NID,
|
|
&nid, &nid_len);
|
|
|
|
switch (res) {
|
|
case 0:
|
|
switch (nid_len) {
|
|
case 1:
|
|
return _got_uint8_value("network ID", (uint8_t *)nid, nid_len, 1, NETDEV_TEST_NID);
|
|
|
|
case 2:
|
|
return _got_uint16_value("network ID", (uint16_t *)nid, nid_len, 1, NETDEV_TEST_NID);
|
|
|
|
case 4:
|
|
return _got_uint32_value("network ID", (uint32_t *)nid, nid_len, 1, NETDEV_TEST_NID);
|
|
|
|
case 8:
|
|
return _got_uint64_value("network ID", (uint64_t *)nid, nid_len, 1, NETDEV_TEST_NID);
|
|
|
|
default:
|
|
printf("Unexpected network ID type of length %u:", nid_len);
|
|
|
|
for (size_t i = 0; i < nid_len; i++) {
|
|
printf(" %02x", nid[i]);
|
|
}
|
|
|
|
printf("\n");
|
|
return 0;
|
|
}
|
|
|
|
case -ENODEV:
|
|
puts("Device was not initialized");
|
|
break;
|
|
|
|
case -ENOTSUP:
|
|
puts("Does not support getting the network ID");
|
|
return 2;
|
|
|
|
case -EOVERFLOW:
|
|
puts("Network ID type bigger then 64 bit.");
|
|
break;
|
|
|
|
default:
|
|
puts("unknown error");
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***********************************
|
|
* test maximum packet size *
|
|
***********************************/
|
|
static int check_max_packet_size(void)
|
|
{
|
|
uint8_t mps[sizeof(uint64_t)];
|
|
size_t mps_len = sizeof(uint64_t);
|
|
int res = dev->driver->get_option(dev, NETDEV_OPT_MAX_PACKET_SIZE,
|
|
&mps, &mps_len);
|
|
|
|
switch (res) {
|
|
case 0:
|
|
switch (mps_len) {
|
|
case 1:
|
|
return _got_uint8_value("maximum packet size", (uint8_t *)mps, mps_len, 0, 0);
|
|
|
|
case 2:
|
|
return _got_uint16_value("maximum packet size", (uint16_t *)mps, mps_len, 0, 0);
|
|
|
|
case 4:
|
|
return _got_uint32_value("maximum packet size", (uint32_t *)mps, mps_len, 0, 0);
|
|
|
|
case 8:
|
|
return _got_uint64_value("maximum packet size", (uint64_t *)mps, mps_len, 0, 0);
|
|
|
|
default:
|
|
printf("Unexpected maximum packet size type of length %u:", mps_len);
|
|
|
|
for (size_t i = 0; i < mps_len; i++) {
|
|
printf(" %02x", mps[i]);
|
|
}
|
|
|
|
printf("\n");
|
|
return 0;
|
|
}
|
|
|
|
case -ENODEV:
|
|
puts("Device was not initialized");
|
|
break;
|
|
|
|
case -ENOTSUP:
|
|
puts("Does not support getting the maximum packet size");
|
|
return 2;
|
|
|
|
case -EOVERFLOW:
|
|
puts("Maximum packet size type bigger then 64 bit.");
|
|
break;
|
|
|
|
default:
|
|
puts("unknown error");
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***********************************
|
|
* test protocol *
|
|
***********************************/
|
|
static int check_protocol(void)
|
|
{
|
|
netdev_proto_t protocol;
|
|
size_t protocol_len = sizeof(netdev_proto_t);
|
|
int res = dev->driver->get_option(dev, NETDEV_OPT_PROTO,
|
|
&protocol, &protocol_len);
|
|
|
|
switch (res) {
|
|
case 0:
|
|
if (protocol_len != sizeof(netdev_proto_t)) {
|
|
puts("Protocol type is not of length sizeof(netdev_proto_t)");
|
|
return 0;
|
|
}
|
|
|
|
switch (protocol) {
|
|
case NETDEV_PROTO_UNKNOWN:
|
|
puts("Got protocol: Unknown communication type");
|
|
return 1;
|
|
|
|
case NETDEV_PROTO_RADIO:
|
|
puts("Got protocol: Radio");
|
|
return 1;
|
|
|
|
case NETDEV_PROTO_802154:
|
|
puts("Got protocol: IEEE 802.15.4");
|
|
return 1;
|
|
|
|
case NETDEV_PROTO_6LOWPAN:
|
|
puts("Got protocol: 6LoWPAN");
|
|
return 1;
|
|
|
|
case NETDEV_PROTO_IPV6:
|
|
puts("Got protocol: IPv6");
|
|
return 1;
|
|
|
|
case NETDEV_PROTO_UDP:
|
|
puts("Got protocol: UDP");
|
|
return 1;
|
|
|
|
case NETDEV_PROTO_TCP:
|
|
puts("Got protocol: TCP");
|
|
return 1;
|
|
|
|
case NETDEV_PROTO_CCNL:
|
|
puts("Got protocol: CCN lite");
|
|
return 1;
|
|
|
|
case NETDEV_PROTO_CC110X:
|
|
puts("Got protocol: CC110x");
|
|
return 1;
|
|
|
|
default:
|
|
puts("You probably have to update this switch-case.");
|
|
return 0;
|
|
}
|
|
|
|
case -ENODEV:
|
|
puts("Device was not initialized");
|
|
break;
|
|
|
|
case -ENOTSUP:
|
|
puts("Does not support getting the protocol");
|
|
return 2;
|
|
|
|
case -EOVERFLOW:
|
|
puts("Protocol type bigger then 64 bit.");
|
|
break;
|
|
|
|
default:
|
|
puts("unknown error");
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*************************************
|
|
* state tests *
|
|
*************************************/
|
|
static int init_state(void)
|
|
{
|
|
int res = dev->driver->set_state(dev, NETDEV_STATE_RX_MODE);
|
|
|
|
switch (res) {
|
|
case 0:
|
|
puts("Device was set to RX mode");
|
|
return 1;
|
|
|
|
case -ENODEV:
|
|
puts("Device was not initialized");
|
|
break;
|
|
|
|
case -ENOTSUP:
|
|
puts("Device does not have a RX mode");
|
|
return 2;
|
|
|
|
case -ETIME:
|
|
puts("Device timed out setting to RX mode");
|
|
break;
|
|
|
|
default:
|
|
puts("unknown error");
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int check_state(void)
|
|
{
|
|
netdev_state_t state;
|
|
int res = dev->driver->get_state(dev, &state);
|
|
|
|
switch (res) {
|
|
case 0:
|
|
switch (state) {
|
|
case NETDEV_STATE_POWER_OFF:
|
|
puts("Device is powered off");
|
|
break;
|
|
|
|
case NETDEV_STATE_POWER_SLEEP:
|
|
puts("Device is sleeping");
|
|
break;
|
|
|
|
case NETDEV_STATE_POWER_IDLE:
|
|
puts("Device is idle");
|
|
break;
|
|
|
|
case NETDEV_STATE_RX_MODE:
|
|
puts("Device is in RX mode");
|
|
break;
|
|
|
|
case NETDEV_STATE_PROMISCUOUS_MODE:
|
|
puts("Device is in promiscous mode");
|
|
break;
|
|
|
|
default:
|
|
puts("Device is in unknown state");
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
|
|
case -ENODEV:
|
|
puts("Device was not initialized");
|
|
break;
|
|
|
|
case -ETIME:
|
|
puts("Device timed out getting to RX mode");
|
|
break;
|
|
|
|
default:
|
|
puts("unknown error");
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#ifdef SENDER
|
|
static int send_packet(void)
|
|
{
|
|
netdev_hlist_t *hlist = NULL;
|
|
netdev_hlist_t header1 = {NULL, NULL, NETDEV_PROTO_UNKNOWN, "header 1,", 9};
|
|
netdev_hlist_t header2 = {NULL, NULL, NETDEV_PROTO_UNKNOWN, "header 2,", 9};
|
|
char payload[] = "payload";
|
|
|
|
netdev_hlist_add(&hlist, &header2);
|
|
netdev_hlist_add(&hlist, &header1);
|
|
|
|
printf("Sending \"%s%s%s\" to", (char *)header1.header, (char *)header2.header,
|
|
payload);
|
|
|
|
switch (dev_address_len) {
|
|
case 1:
|
|
do { /* open block to reduce scope of variable */
|
|
uint8_t dest = NETDEV_TEST_RECEIVER;
|
|
|
|
printf(" %" PRIu8 "\n", dest);
|
|
dev->driver->send_data(dev, &dest, dev_address_len,
|
|
hlist, payload, strlen(payload));
|
|
} while (0);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
do { /* open block to reduce scope of variable */
|
|
uint16_t dest = NETDEV_TEST_RECEIVER;
|
|
|
|
printf(" %" PRIu16 "\n", dest);
|
|
dev->driver->send_data(dev, &dest, dev_address_len,
|
|
hlist, payload, strlen(payload));
|
|
} while (0);
|
|
|
|
break;
|
|
|
|
case 3:
|
|
do { /* open block to reduce scope of variable */
|
|
uint16_t dest_int = HTONS(NETDEV_TEST_RECEIVER);
|
|
uint8_t dest[dev_address_len];
|
|
|
|
memset(dest, 0, dev_address_len - sizeof(uint16_t));
|
|
memcpy(&(dest[dev_address_len - sizeof(uint16_t)]), &dest_int,
|
|
sizeof(uint16_t));
|
|
|
|
for (size_t i = 0; i < dev_address_len; i++) {
|
|
printf(" %02x", dest[i]);
|
|
}
|
|
|
|
puts("");
|
|
|
|
dev->driver->send_data(dev, &dest, dev_address_len,
|
|
hlist, payload, strlen(payload));
|
|
} while (0);
|
|
|
|
case 4:
|
|
do { /* open block to reduce scope of variable */
|
|
uint32_t dest = NETDEV_TEST_RECEIVER;
|
|
|
|
printf(" %" PRIu32 "\n", dest);
|
|
dev->driver->send_data(dev, &dest, dev_address_len, hlist,
|
|
payload, strlen(payload));
|
|
} while (0);
|
|
|
|
break;
|
|
|
|
case 8:
|
|
do { /* open block to reduce scope of variable */
|
|
uint64_t dest = NETDEV_TEST_RECEIVER;
|
|
|
|
printf(" %" PRIu64 "\n", dest);
|
|
dev->driver->send_data(dev, &dest, dev_address_len,
|
|
hlist, payload, strlen(payload));
|
|
} while (0);
|
|
|
|
break;
|
|
|
|
default:
|
|
do { /* open block to reduce scope of variable */
|
|
uint32_t dest_int = HTONL(NETDEV_TEST_RECEIVER);
|
|
uint8_t dest[dev_address_len];
|
|
|
|
memset(dest, 0, dev_address_len - sizeof(uint32_t));
|
|
memcpy(&(dest[dev_address_len - sizeof(uint32_t)]), &dest_int,
|
|
sizeof(uint32_t));
|
|
|
|
for (size_t i = 0; i < dev_address_len; i++) {
|
|
printf(" %02x", dest[i]);
|
|
}
|
|
|
|
puts("");
|
|
|
|
dev->driver->send_data(dev, &dest, dev_address_len,
|
|
hlist, payload, strlen(payload));
|
|
} while (0);
|
|
|
|
break;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
#endif
|
|
|
|
#ifdef RECEIVER
|
|
static int test_callback(netdev_t *rcv_dev, void *src, size_t src_len,
|
|
void *dest, size_t dest_len, void *payload,
|
|
size_t payload_len)
|
|
{
|
|
uint8_t exp_src[dev_address_len];
|
|
uint8_t exp_dest[dev_address_len];
|
|
|
|
if (rcv_dev != dev) {
|
|
printf("cb: Device is not the expected one: %p != %p\n",
|
|
(void *)rcv_dev, (void *)dev);
|
|
return -EINVAL;
|
|
}
|
|
|
|
switch (dev_address_len) {
|
|
case 1:
|
|
exp_src[0] = NETDEV_TEST_SENDER;
|
|
exp_dest[0] = NETDEV_TEST_RECEIVER;
|
|
break;
|
|
|
|
case 2:
|
|
do { /* open block to reduce scope of variable */
|
|
uint16_t *exp_src_ptr = (uint16_t *)exp_src;
|
|
uint16_t *exp_dest_ptr = (uint16_t *)exp_dest;
|
|
*exp_src_ptr = NETDEV_TEST_SENDER;
|
|
*exp_dest_ptr = NETDEV_TEST_RECEIVER;
|
|
} while (0);
|
|
|
|
break;
|
|
|
|
case 3:
|
|
do { /* open block to reduce scope of variable */
|
|
uint16_t exp_src_int = HTONS(NETDEV_TEST_SENDER);
|
|
uint16_t exp_dest_int = HTONS(NETDEV_TEST_RECEIVER);
|
|
memset(exp_dest, 0, dev_address_len - sizeof(uint16_t));
|
|
memset(exp_src, 0, dev_address_len - sizeof(uint16_t));
|
|
memcpy(&(exp_dest[dev_address_len - sizeof(uint16_t)]),
|
|
&exp_dest_int, sizeof(uint16_t));
|
|
memcpy(&(exp_src[dev_address_len - sizeof(uint16_t)]),
|
|
&exp_src_int, sizeof(uint16_t));
|
|
} while (0);
|
|
|
|
break;
|
|
|
|
case 4:
|
|
do { /* open block to reduce scope of variable */
|
|
uint32_t *exp_src_ptr = (uint32_t *)exp_src;
|
|
uint32_t *exp_dest_ptr = (uint32_t *)exp_dest;
|
|
*exp_src_ptr = NETDEV_TEST_SENDER;
|
|
*exp_dest_ptr = NETDEV_TEST_RECEIVER;
|
|
} while (0);
|
|
|
|
break;
|
|
|
|
case 8:
|
|
do { /* open block to reduce scope of variable */
|
|
uint64_t *exp_src_ptr = (uint64_t *)exp_src;
|
|
uint64_t *exp_dest_ptr = (uint64_t *)exp_dest;
|
|
*exp_src_ptr = NETDEV_TEST_SENDER;
|
|
*exp_dest_ptr = NETDEV_TEST_RECEIVER;
|
|
} while (0);
|
|
|
|
break;
|
|
|
|
default:
|
|
do { /* open block to reduce scope of variable */
|
|
uint32_t exp_src_int = HTONL(NETDEV_TEST_SENDER);
|
|
uint32_t exp_dest_int = HTONL(NETDEV_TEST_RECEIVER);
|
|
memset(exp_dest, 0, dev_address_len - sizeof(uint32_t));
|
|
memset(exp_src, 0, dev_address_len - sizeof(uint32_t));
|
|
memcpy(&(exp_dest[dev_address_len - sizeof(uint32_t)]),
|
|
&exp_dest_int, sizeof(uint32_t));
|
|
memcpy(&(exp_src[dev_address_len - sizeof(uint32_t)]),
|
|
&exp_src_int, sizeof(uint32_t));
|
|
} while (0);
|
|
|
|
break;
|
|
}
|
|
|
|
if (src_len != dev_address_len || memcmp(exp_src, src, src_len) != 0) {
|
|
printf("cb: src is not from sender %d\n", NETDEV_TEST_SENDER);
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (dest_len != dev_address_len || memcmp(exp_dest, dest, dest_len) != 0) {
|
|
printf("cb: dest is not for receiver %d\n", NETDEV_TEST_SENDER);
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (strcmp(payload, "header 1,header 2,payload") != 0) {
|
|
puts("cb: payload is not as expected (\"header 1,header 2,payload\")");
|
|
return -EINVAL;
|
|
}
|
|
|
|
printf("Received \"");
|
|
|
|
for (size_t i = 0; i < payload_len; i++) {
|
|
printf("%c", ((char *)payload)[i]);
|
|
}
|
|
|
|
printf("\"\n");
|
|
|
|
printf("Sender was");
|
|
|
|
for (size_t i = 0; i < src_len; i++) {
|
|
printf(" %02x", ((char *)src)[i]);
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
return payload_len;
|
|
}
|
|
|
|
static int init_receiver_callback(void)
|
|
{
|
|
int res = dev->driver->add_receive_data_callback(dev, test_callback);
|
|
|
|
switch (res) {
|
|
case 0:
|
|
puts("Added receive callback successfully.");
|
|
return 1;
|
|
|
|
case -ENODEV:
|
|
puts("Device was not initialized");
|
|
break;
|
|
|
|
case -ENOBUFS:
|
|
puts("Can not add callback: no slot left");
|
|
break;
|
|
|
|
default:
|
|
puts("Unknown error");
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
int main(void)
|
|
{
|
|
int init_res;
|
|
|
|
puts("\nRIOT netdev test");
|
|
dev = NETDEV_DEFAULT;
|
|
|
|
if (dev == NULL) {
|
|
puts("Default device was NULL");
|
|
return 1;
|
|
}
|
|
|
|
printf("Initialized dev ");
|
|
|
|
switch (dev->type) {
|
|
case NETDEV_TYPE_UNKNOWN:
|
|
printf("of unknown type\n");
|
|
break;
|
|
|
|
case NETDEV_TYPE_BASE:
|
|
printf("as basic device\n");
|
|
break;
|
|
|
|
default:
|
|
printf("of undefined type\n");
|
|
break;
|
|
}
|
|
|
|
if (dev->driver == NULL) {
|
|
puts("Default driver is defined as NULL!");
|
|
return 1;
|
|
}
|
|
|
|
dev->driver->init(dev);
|
|
|
|
if (!(init_res = init_channel())) {
|
|
return 1;
|
|
}
|
|
|
|
if (check_channel() == 0) {
|
|
printf("Channel is not as expected. ");
|
|
|
|
if (init_res == 2) {
|
|
printf("But initialization is not supported. Continuing.\n");
|
|
}
|
|
else {
|
|
printf("Aborting\n");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (!(init_res = init_address())) {
|
|
return 1;
|
|
}
|
|
|
|
if (check_address() == 0) {
|
|
printf("Address is not as expected. ");
|
|
|
|
if (init_res == 2) {
|
|
printf("But initialization is not supported. Continuing.\n");
|
|
}
|
|
else {
|
|
printf("Aborting\n");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (!(init_res = init_long_address())) {
|
|
return 1;
|
|
}
|
|
|
|
if (check_long_address() == 0) {
|
|
printf("Long address is not as expected. ");
|
|
|
|
if (init_res == 2) {
|
|
printf("But initialization is not supported. Continuing.\n");
|
|
}
|
|
else {
|
|
printf("Aborting\n");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (!(init_res = init_nid())) {
|
|
return 1;
|
|
}
|
|
|
|
if (check_nid() == 0) {
|
|
printf("Network ID is not as expected. ");
|
|
|
|
if (init_res == 2) {
|
|
printf("But initialization is not supported. Continuing.\n");
|
|
}
|
|
else {
|
|
printf("Aborting\n");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (check_max_packet_size() == 0) {
|
|
return 1;
|
|
}
|
|
|
|
if (check_protocol() == 0) {
|
|
return 1;
|
|
}
|
|
|
|
if (!init_state()) {
|
|
return 1;
|
|
}
|
|
|
|
if (!check_state()) {
|
|
return 1;
|
|
}
|
|
|
|
#ifdef SENDER
|
|
|
|
if (!send_packet()) {
|
|
return 1;
|
|
}
|
|
|
|
#elif RECEIVER
|
|
|
|
if (!init_receiver_callback()) {
|
|
return 1;
|
|
}
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
#else
|
|
|
|
int main(void)
|
|
{
|
|
puts("\nRIOT netdev test");
|
|
puts("Default netdev type and driver unknown!");
|
|
|
|
return 0;
|
|
}
|
|
|
|
#endif /* !NETDEV_DEFAULT */
|