blob: 43fcee530ec0fac573d6237b5f0a6c6a10abe985 [file] [log] [blame]
/* main.c - Application main entry point */
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#define NET_LOG_LEVEL CONFIG_NET_L2_ETHERNET_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL);
#include <zephyr/types.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <zephyr/sys/printk.h>
#include <zephyr/linker/sections.h>
#include <zephyr/random/random.h>
#include <zephyr/ztest.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/wifi_mgmt.h>
#include <zephyr/net/wifi_nm.h>
#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
#define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__)
#else
#define DBG(fmt, ...)
#endif
struct wifi_drv_context {
struct net_if *iface;
uint8_t mac_addr[6];
enum ethernet_if_types eth_if_type;
};
static struct wifi_drv_context wifi_context;
bool wifi_nm_op_called;
bool wifi_offload_op_called;
static void wifi_iface_init(struct net_if *iface)
{
const struct device *dev = net_if_get_device(iface);
struct wifi_drv_context *context = dev->data;
struct ethernet_context *eth_ctx = net_if_l2_data(iface);
net_if_set_link_addr(iface, context->mac_addr,
sizeof(context->mac_addr),
NET_LINK_ETHERNET);
eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI;
ethernet_init(iface);
}
static int wifi_scan(const struct device *dev, struct wifi_scan_params *params,
scan_result_cb_t cb)
{
ARG_UNUSED(dev);
ARG_UNUSED(params);
ARG_UNUSED(cb);
wifi_offload_op_called = true;
return 0;
}
static struct wifi_mgmt_ops wifi_mgmt_api = {
.scan = wifi_scan,
};
static struct net_wifi_mgmt_offload api_funcs = {
.wifi_iface.iface_api.init = wifi_iface_init,
.wifi_mgmt_api = &wifi_mgmt_api,
};
static void generate_mac(uint8_t *mac_addr)
{
/* 00-00-5E-00-53-xx Documentation RFC 7042 */
mac_addr[0] = 0x00;
mac_addr[1] = 0x00;
mac_addr[2] = 0x5E;
mac_addr[3] = 0x00;
mac_addr[4] = 0x53;
mac_addr[5] = sys_rand32_get();
}
static int wifi_init(const struct device *dev)
{
struct wifi_drv_context *context = dev->data;
context->eth_if_type = L2_ETH_IF_TYPE_WIFI;
generate_mac(context->mac_addr);
return 0;
}
ETH_NET_DEVICE_INIT(wlan0, "wifi_test",
wifi_init, NULL,
&wifi_context, NULL, CONFIG_ETH_INIT_PRIORITY,
&api_funcs, NET_ETH_MTU);
static int wifi_nm_scan(const struct device *dev, struct wifi_scan_params *params,
scan_result_cb_t cb)
{
ARG_UNUSED(dev);
ARG_UNUSED(params);
ARG_UNUSED(cb);
wifi_nm_op_called = true;
return 0;
}
static struct wifi_mgmt_ops wifi_nm_test_ops = {
.scan = wifi_nm_scan,
};
DEFINE_WIFI_NM_INSTANCE(test, &wifi_nm_test_ops);
static int request_scan(void)
{
struct net_if *iface = net_if_get_first_wifi();
if (net_mgmt(NET_REQUEST_WIFI_SCAN, iface, NULL, 0)) {
printk("Scan request failed\n");
return -ENOEXEC;
}
return 0;
}
ZTEST(net_wifi, test_wifi_offload)
{
int ret;
#ifdef CONFIG_WIFI_NM
struct wifi_nm_instance *nm = wifi_nm_get_instance("test");
if (wifi_nm_get_instance_iface(net_if_get_first_wifi())) {
ret = wifi_nm_unregister_mgd_iface(nm, net_if_get_first_wifi());
zassert_equal(ret, 0, "Failed to unregister managed interface");
}
#endif /* CONFIG_WIFI_NM */
ret = request_scan();
zassert_equal(ret, 0, "Scan request failed");
zassert_true(wifi_offload_op_called, "Scan callback not called");
}
ZTEST(net_wifi, test_wifi_nm_managed)
{
int ret;
struct wifi_nm_instance *nm = wifi_nm_get_instance("test");
zassert_equal(nm->ops, &wifi_nm_test_ops,
"Invalid wifi nm ops");
/* Offload: in presence of registered NM but with no managed
* interfaces.
*/
ret = request_scan();
zassert_equal(ret, 0, "Scan request failed");
zassert_true(wifi_offload_op_called, "Scan callback not called");
ret = wifi_nm_register_mgd_iface(nm, net_if_get_first_wifi());
zassert_equal(ret, 0, "Failed to register managed interface");
zassert_equal(nm->ops, &wifi_nm_test_ops,
"Invalid wifi nm ops");
ret = request_scan();
zassert_equal(ret, 0, "Scan request failed");
zassert_true(wifi_nm_op_called, "Scan callback not called");
}
ZTEST_SUITE(net_wifi, NULL, NULL, NULL, NULL, NULL);