tests: Add grounds for IEEE 802.15.4 stack tests.

First test is a unit test for frame parsing

Change-Id: I080d64a71fe4b6ff00e071a0cdee97ab9cd922d5
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2016-06-20 12:15:29 +02:00 committed by Jukka Rissanen
commit 11c9b8dac7
7 changed files with 387 additions and 0 deletions

View file

@ -0,0 +1,6 @@
BOARD ?= qemu_x86
MDEF_FILE = prj.mdef
KERNEL_TYPE ?= nano
CONF_FILE = prj_$(ARCH).conf
include $(ZEPHYR_BASE)/Makefile.inc

View file

@ -0,0 +1,5 @@
% Application : Network test
% TASK NAME PRIO ENTRY STACK GROUPS
% ===================================================
TASK MAIN 7 main 2048 [EXE]

View file

@ -0,0 +1,17 @@
CONFIG_NETWORKING=y
CONFIG_NET_YAIP=y
CONFIG_NET_BUF=y
CONFIG_NET_IPV6=y
CONFIG_NET_IPV6_NO_ND=y
CONFIG_NET_IPV6_NO_DAD=y
CONFIG_NET_L2_IEEE802154=y
CONFIG_NET_L2_IEEE802154_DEBUG=y
CONFIG_MAIN_STACK_SIZE=2048
CONFIG_NET_NBUF_RX_COUNT=5
CONFIG_NET_NBUF_TX_COUNT=5
CONFIG_NET_NBUF_DATA_COUNT=10
CONFIG_NET_LOG=y
CONFIG_SYS_LOG_SHOW_COLOR=y
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_NETWORK_IP_STACK_DEBUG_IPV6=y

View file

@ -0,0 +1,6 @@
ccflags-y += -I${ZEPHYR_BASE}/tests/include
ccflags-y += -I${ZEPHYR_BASE}/net/yaip/l2/ieee802154
ccflags-y += -I${ZEPHYR_BASE}/net/yaip/
obj-y = ieee802154_test.o \
ieee802154_fake_driver.o

View file

@ -0,0 +1,137 @@
/*
* Copyright (c) 2016 Intel Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zephyr.h>
#include <tc_util.h>
#include <net/nbuf.h>
/** FAKE ieee802.15.4 driver **/
#include <net/ieee802154_radio.h>
extern struct net_buf *current_buf;
extern struct nano_sem driver_lock;
static int fake_cca(struct device *dev)
{
return 0;
}
static int fake_set_channel(struct device *dev, uint16_t channel)
{
TC_PRINT("Channel %u\n", channel);
return 0;
}
static int fake_set_pan_id(struct device *dev, uint16_t pan_id)
{
TC_PRINT("PAN id 0x%x\n", pan_id);
return 0;
}
static int fake_set_short_addr(struct device *dev, uint16_t short_addr)
{
TC_PRINT("Short address: 0x%x\n", short_addr);
return 0;
}
static int fake_set_ieee_addr(struct device *dev, const uint8_t *ieee_addr)
{
TC_PRINT("IEEE address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
ieee_addr[0], ieee_addr[1], ieee_addr[2], ieee_addr[3],
ieee_addr[4], ieee_addr[5], ieee_addr[6], ieee_addr[7]);
return 0;
}
static int fake_set_txpower(struct device *dev, int16_t dbm)
{
TC_PRINT("TX power %d dbm\n", dbm);
return 0;
}
static int fake_tx(struct device *dev, struct net_buf *buf)
{
TC_PRINT("Sending buffer %p - length %u\n",
buf, net_buf_frags_len(buf));
current_buf = net_buf_ref(buf);
nano_sem_give(&driver_lock);
return 0;
}
static int fake_start(struct device *dev)
{
TC_PRINT("FAKE ieee802154 driver started\n");
return 0;
}
static int fake_stop(struct device *dev)
{
TC_PRINT("FAKE ieee802154 driver stopped\n");
return 0;
}
static void fake_iface_init(struct net_if *iface)
{
struct ieee802154_context *ctx = net_if_l2_data(iface);
static uint8_t mac[8] = { 0x00, 0x12, 0x4b, 0x00,
0x00, 0x9e, 0xa3, 0xc2 };
net_if_set_link_addr(iface, mac, 8);
ctx->pan_id = 0xabcd;
ctx->channel = 26;
ctx->sequence = 62;
TC_PRINT("FAKE ieee802154 iface initialized\n");
}
static int fake_init(struct device *dev)
{
fake_stop(dev);
return 0;
}
static struct ieee802154_radio_api fake_radio_api = {
.iface_api.init = fake_iface_init,
.iface_api.send = ieee802154_radio_send,
.cca = fake_cca,
.set_channel = fake_set_channel,
.set_pan_id = fake_set_pan_id,
.set_short_addr = fake_set_short_addr,
.set_ieee_addr = fake_set_ieee_addr,
.set_txpower = fake_set_txpower,
.start = fake_start,
.stop = fake_stop,
.tx = fake_tx,
};
NET_DEVICE_INIT(fake, "fake_ieee802154",
fake_init, NULL, NULL,
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
&fake_radio_api, IEEE802154_L2,
NET_L2_GET_CTX_TYPE(IEEE802154_L2), 127);

View file

@ -0,0 +1,211 @@
/*
* Copyright (c) 2016 Intel Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zephyr.h>
#include <tc_util.h>
#include <net/net_ip.h>
#include <net/nbuf.h>
#include <ieee802154_frame.h>
#include <ipv6.h>
struct ieee802154_pkt_test {
char *name;
struct in6_addr src;
struct in6_addr dst;
uint8_t *pkt;
uint8_t length;
struct {
struct ieee802154_fcf_seq *fc_seq;
struct ieee802154_address_field *dst_addr;
struct ieee802154_address_field *src_addr;
} mhr_check;
};
uint8_t ns_pkt[] = {
0x41, 0xd8, 0x3e, 0xcd, 0xab, 0xff, 0xff, 0xc2, 0xa3, 0x9e, 0x00,
0x00, 0x4b, 0x12, 0x00, 0x7b, 0x09, 0x3a, 0x20, 0x01, 0x0d, 0xb8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x02, 0x01, 0xff, 0x00, 0x00, 0x01, 0x87, 0x00, 0x2e, 0xad,
0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02,
0x00, 0x12, 0x4b, 0x00, 0x00, 0x9e, 0xa3, 0xc2, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3d, 0x74
};
struct ieee802154_pkt_test test_ns_pkt = {
.name = "NS frame",
.src = { { { 0x20, 0x01, 0xdb, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } },
.dst = { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x01 } } },
.pkt = ns_pkt,
.length = sizeof(ns_pkt),
.mhr_check.fc_seq = (struct ieee802154_fcf_seq *)ns_pkt,
.mhr_check.dst_addr = (struct ieee802154_address_field *)(ns_pkt + 3),
.mhr_check.src_addr = (struct ieee802154_address_field *)(ns_pkt + 7),
};
struct net_buf *current_buf;
struct nano_sem driver_lock;
struct net_if *iface;
static void pkt_hexdump(uint8_t *pkt, uint8_t length)
{
int i;
TC_PRINT(" -> Packet content:\n");
for (i = 0; i < length;) {
int j;
TC_PRINT("\t");
for (j = 0; j < 10 && i < length; j++, i++) {
TC_PRINT("%02x ", *pkt);
pkt++;
}
TC_PRINT("\n");
}
}
static void ieee_addr_hexdump(uint8_t *addr, uint8_t length)
{
int i;
TC_PRINT(" -> IEEE 802.15.4 Address: ");
for (i = 0; i < length-1; i++) {
TC_PRINT("%02x:", *addr);
addr++;
}
TC_PRINT("%02x\n", *addr);
}
static inline int test_packet_parsing(struct ieee802154_pkt_test *t)
{
struct ieee802154_mpdu mpdu;
TC_PRINT("- Parsing packet 0x%p of frame %s\n", t->pkt, t->name);
if (!ieee802154_validate_frame(t->pkt, t->length, &mpdu)) {
TC_ERROR("*** Could not validate frame %s\n", t->name);
return TC_FAIL;
}
if (mpdu.mhr.fs != t->mhr_check.fc_seq ||
mpdu.mhr.dst_addr != t->mhr_check.dst_addr ||
mpdu.mhr.src_addr != t->mhr_check.src_addr) {
TC_PRINT("d: %p vs %p -- s: %p vs %p\n",
mpdu.mhr.dst_addr, t->mhr_check.dst_addr,
mpdu.mhr.src_addr, t->mhr_check.src_addr);
TC_ERROR("*** Wrong MPDU information on frame %s\n",
t->name);
return TC_FAIL;
}
return TC_PASS;
}
static inline int test_ns_sending(struct ieee802154_pkt_test *t)
{
struct ieee802154_mpdu mpdu;
TC_PRINT("- Sending NS packet\n");
if (net_ipv6_send_ns(iface, NULL, &t->src, &t->dst, &t->dst, false)) {
TC_ERROR("*** Could not create IPv6 NS packet\n");
return TC_FAIL;
}
nano_sem_take(&driver_lock, MSEC(10));
if (!current_buf) {
TC_ERROR("*** Could not send IPv6 NS packet\n");
return TC_FAIL;
}
pkt_hexdump(net_nbuf_ll(current_buf), net_buf_frags_len(current_buf));
if (!ieee802154_validate_frame(net_nbuf_ll(current_buf),
net_buf_frags_len(current_buf), &mpdu)) {
TC_ERROR("*** Sent packet is not valid\n");
net_buf_unref(current_buf);
return TC_FAIL;
}
net_buf_unref(current_buf);
current_buf = NULL;
return TC_PASS;
}
static inline int initialize_test_environment(void)
{
struct device *dev;
nano_sem_init(&driver_lock);
current_buf = NULL;
dev = device_get_binding("fake_ieee802154");
if (!dev) {
TC_ERROR("*** Could not get fake device\n");
return TC_FAIL;
}
iface = net_if_lookup_by_dev(dev);
if (!iface) {
TC_ERROR("*** Could not get fake iface\n");
return TC_FAIL;
}
TC_PRINT("Fake IEEE 802.15.4 network interface ready\n");
ieee_addr_hexdump(iface->link_addr.addr, 8);
return TC_PASS;
}
void main(void)
{
int status = TC_FAIL;
TC_PRINT("Starting ieee802154 stack test\n");
if (initialize_test_environment() != TC_PASS) {
goto end;
}
if (test_packet_parsing(&test_ns_pkt) != TC_PASS) {
goto end;
}
if (test_ns_sending(&test_ns_pkt) != TC_PASS) {
goto end;
}
status = TC_PASS;
end:
TC_END_RESULT(status);
TC_END_REPORT(status);
}

View file

@ -0,0 +1,5 @@
[test]
tags = net
arch_whitelist = x86
platform_whitelist = qemu_x86
build_only = true