1 /* main.c - Application main entry point */
2 
3 /*
4  * Copyright (c) 2023 Nordic Semiconductor ASA
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #define NET_LOG_LEVEL CONFIG_NET_L2_ETHERNET_LOG_LEVEL
10 
11 #include <zephyr/logging/log.h>
12 LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL);
13 
14 #include <zephyr/types.h>
15 #include <stdbool.h>
16 #include <stddef.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <zephyr/sys/printk.h>
20 #include <zephyr/linker/sections.h>
21 #include <zephyr/random/random.h>
22 
23 #include <zephyr/ztest.h>
24 
25 #include <zephyr/net/net_if.h>
26 #include <zephyr/net/wifi_mgmt.h>
27 #include <zephyr/net/wifi_nm.h>
28 
29 #if NET_LOG_LEVEL >= LOG_LEVEL_DBG
30 #define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__)
31 #else
32 #define DBG(fmt, ...)
33 #endif
34 
35 struct wifi_drv_context {
36 	struct net_if *iface;
37 	uint8_t mac_addr[6];
38 	enum ethernet_if_types eth_if_type;
39 };
40 
41 static struct wifi_drv_context wifi_context;
42 
43 bool wifi_nm_op_called;
44 bool wifi_offload_op_called;
45 
wifi_iface_init(struct net_if * iface)46 static void wifi_iface_init(struct net_if *iface)
47 {
48 	const struct device *dev = net_if_get_device(iface);
49 	struct wifi_drv_context *context = dev->data;
50 	struct ethernet_context *eth_ctx = net_if_l2_data(iface);
51 
52 	net_if_set_link_addr(iface, context->mac_addr,
53 			     sizeof(context->mac_addr),
54 			     NET_LINK_ETHERNET);
55 
56 	eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI;
57 
58 	ethernet_init(iface);
59 }
60 
wifi_scan(const struct device * dev,struct wifi_scan_params * params,scan_result_cb_t cb)61 static int wifi_scan(const struct device *dev, struct wifi_scan_params *params,
62 		     scan_result_cb_t cb)
63 {
64 	ARG_UNUSED(dev);
65 	ARG_UNUSED(params);
66 	ARG_UNUSED(cb);
67 
68 	wifi_offload_op_called = true;
69 
70 	return 0;
71 }
72 
73 static struct wifi_mgmt_ops wifi_mgmt_api = {
74 	.scan		= wifi_scan,
75 };
76 
77 static struct net_wifi_mgmt_offload api_funcs = {
78 	.wifi_iface.iface_api.init = wifi_iface_init,
79 	.wifi_mgmt_api = &wifi_mgmt_api,
80 };
81 
generate_mac(uint8_t * mac_addr)82 static void generate_mac(uint8_t *mac_addr)
83 {
84 	/* 00-00-5E-00-53-xx Documentation RFC 7042 */
85 	mac_addr[0] = 0x00;
86 	mac_addr[1] = 0x00;
87 	mac_addr[2] = 0x5E;
88 	mac_addr[3] = 0x00;
89 	mac_addr[4] = 0x53;
90 	mac_addr[5] = sys_rand8_get();
91 }
92 
wifi_init(const struct device * dev)93 static int wifi_init(const struct device *dev)
94 {
95 	struct wifi_drv_context *context = dev->data;
96 
97 	context->eth_if_type = L2_ETH_IF_TYPE_WIFI;
98 
99 	generate_mac(context->mac_addr);
100 
101 	return 0;
102 }
103 
104 ETH_NET_DEVICE_INIT(wlan0, "wifi_test",
105 		    wifi_init, NULL,
106 		    &wifi_context, NULL, CONFIG_ETH_INIT_PRIORITY,
107 		    &api_funcs, NET_ETH_MTU);
108 
wifi_nm_scan(const struct device * dev,struct wifi_scan_params * params,scan_result_cb_t cb)109 static int wifi_nm_scan(const struct device *dev, struct wifi_scan_params *params,
110 			scan_result_cb_t cb)
111 {
112 	ARG_UNUSED(dev);
113 	ARG_UNUSED(params);
114 	ARG_UNUSED(cb);
115 
116 	wifi_nm_op_called = true;
117 
118 	return 0;
119 }
120 
121 static struct wifi_mgmt_ops wifi_nm_test_ops = {
122 	.scan		= wifi_nm_scan,
123 };
124 
125 DEFINE_WIFI_NM_INSTANCE(test, &wifi_nm_test_ops);
126 
request_scan(void)127 static int request_scan(void)
128 {
129 	struct net_if *iface = net_if_get_first_wifi();
130 
131 	if (net_mgmt(NET_REQUEST_WIFI_SCAN, iface, NULL, 0)) {
132 		printk("Scan request failed\n");
133 
134 		return -ENOEXEC;
135 	}
136 
137 	return 0;
138 }
139 
ZTEST(net_wifi,test_wifi_offload)140 ZTEST(net_wifi, test_wifi_offload)
141 {
142 
143 	int ret;
144 #ifdef CONFIG_WIFI_NM
145 	struct wifi_nm_instance *nm = wifi_nm_get_instance("test");
146 
147 	if (wifi_nm_get_instance_iface(net_if_get_first_wifi())) {
148 		ret = wifi_nm_unregister_mgd_iface(nm, net_if_get_first_wifi());
149 		zassert_equal(ret, 0, "Failed to unregister managed interface");
150 	}
151 #endif /* CONFIG_WIFI_NM */
152 
153 	ret = request_scan();
154 	zassert_equal(ret, 0, "Scan request failed");
155 	zassert_true(wifi_offload_op_called, "Scan callback not called");
156 }
157 
ZTEST(net_wifi,test_wifi_nm_managed)158 ZTEST(net_wifi, test_wifi_nm_managed)
159 {
160 
161 	int ret;
162 	struct wifi_nm_instance *nm = wifi_nm_get_instance("test");
163 
164 	zassert_equal(nm->ops, &wifi_nm_test_ops,
165 		      "Invalid wifi nm ops");
166 
167 	/* Offload: in presence of registered NM but with no managed
168 	 *          interfaces.
169 	 */
170 	ret = request_scan();
171 	zassert_equal(ret, 0, "Scan request failed");
172 	zassert_true(wifi_offload_op_called, "Scan callback not called");
173 
174 	ret = wifi_nm_register_mgd_iface(nm, net_if_get_first_wifi());
175 	zassert_equal(ret, 0, "Failed to register managed interface");
176 
177 	zassert_equal(nm->ops, &wifi_nm_test_ops,
178 		      "Invalid wifi nm ops");
179 
180 	ret = request_scan();
181 	zassert_equal(ret, 0, "Scan request failed");
182 	zassert_true(wifi_nm_op_called, "Scan callback not called");
183 }
184 
185 
186 ZTEST_SUITE(net_wifi, NULL, NULL, NULL, NULL, NULL);
187