tests: net: l2: ieee802154: active scan shell/mgmnt coverage

This change introduces integration test coverage for the
stack's scan shell command including the underlying net
management and command handling methods.

Later changes will build on this test to ensure that
changes to command handling will not break backwards
compatibility

This is also the reason why a separate test suite and
test file are being introduced already as further tests
will be added later on. We avoid having to move code
and thereby loose history.

Signed-off-by: Florian Grandel <fgrandel@code-for-humans.de>
This commit is contained in:
Florian Grandel 2023-05-18 23:08:29 +02:00 committed by Carles Cufí
parent 4fcdfab7d9
commit 988ffe9c48
4 changed files with 188 additions and 5 deletions

View file

@ -35,3 +35,11 @@ CONFIG_ZTEST_STACK_SIZE=3072
CONFIG_ZTEST=y
CONFIG_ZTEST_NEW_API=y
CONFIG_SHELL=y
CONFIG_SHELL_BACKEND_SERIAL=n
CONFIG_SHELL_BACKEND_DUMMY=y
CONFIG_SHELL_CMD_BUFF_SIZE=90
CONFIG_SHELL_PRINTF_BUFF_SIZE=15
CONFIG_SHELL_METAKEYS=n
CONFIG_NET_L2_IEEE802154_SHELL=y

View file

@ -17,8 +17,8 @@ LOG_MODULE_REGISTER(net_ieee802154_fake_driver, LOG_LEVEL_DBG);
/** FAKE ieee802.15.4 driver **/
#include <zephyr/net/ieee802154_radio.h>
extern struct net_pkt *current_pkt;
extern struct k_sem driver_lock;
struct net_pkt *current_pkt;
K_SEM_DEFINE(driver_lock, 0, UINT_MAX);
static enum ieee802154_hw_caps fake_get_capabilities(const struct device *dev)
{

View file

@ -0,0 +1,173 @@
/*
* Copyright (c) 2023 Florian Grandel
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_ieee802154_mgmt_test, LOG_LEVEL_DBG);
#include <string.h>
#include <zephyr/kernel.h>
#include <zephyr/ztest.h>
#include <zephyr/net/ieee802154_mgmt.h>
#include <zephyr/net/net_mgmt.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/shell/shell.h>
#include <ieee802154_frame.h>
extern struct net_pkt *current_pkt;
extern struct k_sem driver_lock;
static struct net_if *iface;
static struct net_mgmt_event_callback scan_cb;
K_SEM_DEFINE(scan_lock, 0, 1);
#define EXPECTED_COORDINATOR_LQI 15U
#define EXPECTED_COORDINATOR_PAN_LE 0xcd, 0xab
#define EXPECTED_COORDINATOR_PAN_CPU_ORDER 0xabcd
#define EXPECTED_COORDINATOR_ADDR_LE 0xc2, 0xa3, 0x9e, 0x00, 0x00, 0x4b, 0x12, 0x00
#define EXPECTED_COORDINATOR_ADDR_BE 0x00, 0x12, 0x4b, 0x00, 0x00, 0x9e, 0xa3, 0xc2
static void scan_result_cb(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
struct net_if *iface)
{
struct ieee802154_context *ctx = net_if_l2_data(iface);
struct ieee802154_req_params *scan_ctx = ctx->scan_ctx;
uint8_t expected_coordinator_address[] = {EXPECTED_COORDINATOR_ADDR_BE};
/* No need for scan_ctx locking as we should execute exclusively. */
zassert_not_null(scan_ctx);
zassert_equal(EXPECTED_COORDINATOR_PAN_CPU_ORDER, scan_ctx->pan_id,
"Scan did not receive correct PAN id.");
zassert_equal(IEEE802154_EXT_ADDR_LENGTH, scan_ctx->len,
"Scan did not receive correct co-ordinator address length.");
zassert_mem_equal(expected_coordinator_address, scan_ctx->addr, IEEE802154_EXT_ADDR_LENGTH);
zassert_equal(EXPECTED_COORDINATOR_LQI, scan_ctx->lqi,
"Scan did not receive correct link quality indicator.");
k_sem_give(&scan_lock);
}
void test_beacon_request(struct ieee802154_mpdu *mpdu)
{
struct ieee802154_command *cmd = mpdu->command;
zassert_equal(IEEE802154_CFI_BEACON_REQUEST, cmd->cfi, "Not a beacon request.");
zassert_equal(IEEE802154_ADDR_MODE_SHORT, mpdu->mhr.fs->fc.dst_addr_mode,
"Beacon request: invalid destination address mode.");
zassert_equal(IEEE802154_BROADCAST_ADDRESS, mpdu->mhr.dst_addr->plain.addr.short_addr,
"Beacon request: destination address should be broadcast address.");
zassert_equal(IEEE802154_BROADCAST_PAN_ID, mpdu->mhr.dst_addr->plain.pan_id,
"Beacon request: destination PAN should be broadcast PAN.");
}
void test_scan_shell_cmd(void)
{
struct ieee802154_mpdu mpdu = {0};
int ret;
ret = shell_execute_cmd(NULL, "ieee802154 scan active 11 500");
zassert_equal(0, ret, "Active scan failed: %d", ret);
/* Expect the beacon to have been received and handled already by the scan command. */
zassert_equal(0, k_sem_take(&scan_lock, K_NO_WAIT), "Active scan: did not receive beacon.");
zassert_not_null(current_pkt);
if (!ieee802154_validate_frame(net_pkt_data(current_pkt), net_pkt_get_len(current_pkt),
&mpdu)) {
NET_ERR("*** Could not parse beacon request.\n");
ztest_test_fail();
goto release_frag;
}
test_beacon_request(&mpdu);
release_frag:
net_pkt_frag_unref(current_pkt->frags);
current_pkt->frags = NULL;
}
ZTEST(ieee802154_l2_shell, test_active_scan)
{
uint8_t beacon_pkt[] = {
0x00, 0xd0, /* FCF */
0x11, /* Sequence Number: 17 */
EXPECTED_COORDINATOR_PAN_LE, /* Source PAN */
EXPECTED_COORDINATOR_ADDR_LE, /* Extended Source Address */
0x00, 0xc0, /* Superframe Specification: PAN coordinator + association permitted */
0x00, /* GTS */
0x00, /* Pending Addresses */
0x00, 0x00 /* Payload */
};
struct net_pkt *pkt;
pkt = net_pkt_rx_alloc_with_buffer(iface, sizeof(beacon_pkt), AF_UNSPEC, 0, K_FOREVER);
if (!pkt) {
NET_ERR("*** No buffer to allocate\n");
ztest_test_fail();
return;
}
net_pkt_set_ieee802154_lqi(pkt, EXPECTED_COORDINATOR_LQI);
net_buf_add_mem(pkt->buffer, beacon_pkt, sizeof(beacon_pkt));
if (net_recv_data(iface, pkt) < 0) {
NET_ERR("Recv data failed");
net_pkt_unref(pkt);
ztest_test_fail();
return;
}
net_mgmt_init_event_callback(&scan_cb, scan_result_cb, NET_EVENT_IEEE802154_SCAN_RESULT);
net_mgmt_add_event_callback(&scan_cb);
test_scan_shell_cmd();
net_mgmt_del_event_callback(&scan_cb);
}
static void *test_setup(void)
{
const struct device *dev = device_get_binding("fake_ieee802154");
k_sem_reset(&driver_lock);
if (!dev) {
NET_ERR("*** Could not get fake device\n");
return NULL;
}
iface = net_if_lookup_by_dev(dev);
if (!iface) {
NET_ERR("*** Could not get fake iface\n");
return NULL;
}
NET_INFO("Fake IEEE 802.15.4 network interface ready\n");
current_pkt = net_pkt_rx_alloc(K_FOREVER);
if (!current_pkt) {
NET_ERR("*** No buffer to allocate\n");
return false;
}
return NULL;
}
static void test_teardown(void *test_fixture)
{
ARG_UNUSED(test_fixture);
net_pkt_unref(current_pkt);
current_pkt = NULL;
}
ZTEST_SUITE(ieee802154_l2_shell, NULL, test_setup, NULL, NULL, test_teardown);

View file

@ -156,9 +156,10 @@ uint8_t raw_payload[] = {
#define RAW_MAC_PAYLOAD_START_INDEX 17
#define RAW_MAC_PAYLOAD_LENGTH 3
struct net_pkt *current_pkt;
struct net_if *iface;
K_SEM_DEFINE(driver_lock, 0, UINT_MAX);
extern struct net_pkt *current_pkt;
extern struct k_sem driver_lock;
static struct net_if *iface;
static void pkt_hexdump(uint8_t *pkt, uint8_t length)
{
@ -1102,6 +1103,7 @@ static void test_teardown(void *test_fixture)
ARG_UNUSED(test_fixture);
net_pkt_unref(current_pkt);
current_pkt = NULL;
}
ZTEST(ieee802154_l2, test_parsing_ns_pkt)