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:
parent
4fcdfab7d9
commit
988ffe9c48
|
@ -35,3 +35,11 @@ CONFIG_ZTEST_STACK_SIZE=3072
|
||||||
|
|
||||||
CONFIG_ZTEST=y
|
CONFIG_ZTEST=y
|
||||||
CONFIG_ZTEST_NEW_API=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
|
||||||
|
|
|
@ -17,8 +17,8 @@ LOG_MODULE_REGISTER(net_ieee802154_fake_driver, LOG_LEVEL_DBG);
|
||||||
/** FAKE ieee802.15.4 driver **/
|
/** FAKE ieee802.15.4 driver **/
|
||||||
#include <zephyr/net/ieee802154_radio.h>
|
#include <zephyr/net/ieee802154_radio.h>
|
||||||
|
|
||||||
extern struct net_pkt *current_pkt;
|
struct net_pkt *current_pkt;
|
||||||
extern struct k_sem driver_lock;
|
K_SEM_DEFINE(driver_lock, 0, UINT_MAX);
|
||||||
|
|
||||||
static enum ieee802154_hw_caps fake_get_capabilities(const struct device *dev)
|
static enum ieee802154_hw_caps fake_get_capabilities(const struct device *dev)
|
||||||
{
|
{
|
||||||
|
|
173
tests/net/ieee802154/l2/src/ieee802154_shell_test.c
Normal file
173
tests/net/ieee802154/l2/src/ieee802154_shell_test.c
Normal 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);
|
|
@ -156,9 +156,10 @@ uint8_t raw_payload[] = {
|
||||||
#define RAW_MAC_PAYLOAD_START_INDEX 17
|
#define RAW_MAC_PAYLOAD_START_INDEX 17
|
||||||
#define RAW_MAC_PAYLOAD_LENGTH 3
|
#define RAW_MAC_PAYLOAD_LENGTH 3
|
||||||
|
|
||||||
struct net_pkt *current_pkt;
|
extern struct net_pkt *current_pkt;
|
||||||
struct net_if *iface;
|
extern struct k_sem driver_lock;
|
||||||
K_SEM_DEFINE(driver_lock, 0, UINT_MAX);
|
|
||||||
|
static struct net_if *iface;
|
||||||
|
|
||||||
static void pkt_hexdump(uint8_t *pkt, uint8_t length)
|
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);
|
ARG_UNUSED(test_fixture);
|
||||||
|
|
||||||
net_pkt_unref(current_pkt);
|
net_pkt_unref(current_pkt);
|
||||||
|
current_pkt = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZTEST(ieee802154_l2, test_parsing_ns_pkt)
|
ZTEST(ieee802154_l2, test_parsing_ns_pkt)
|
||||||
|
|
Loading…
Reference in a new issue