1 /*
2  * Copyright (c) 2023 Florian Grandel
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(net_ieee802154_mgmt_test, LOG_LEVEL_DBG);
9 
10 #include <string.h>
11 
12 #include <zephyr/kernel.h>
13 #include <zephyr/ztest.h>
14 
15 #include <zephyr/net/ieee802154.h>
16 #include <zephyr/net/ieee802154_mgmt.h>
17 #include <zephyr/net/net_mgmt.h>
18 #include <zephyr/net/net_if.h>
19 #include <zephyr/net/net_pkt.h>
20 #include <zephyr/shell/shell.h>
21 
22 #include <ieee802154_frame.h>
23 
24 extern struct net_pkt *current_pkt;
25 extern struct k_sem driver_lock;
26 extern uint8_t mock_ext_addr_be[8];
27 
28 static struct net_if *net_iface;
29 
30 static struct net_mgmt_event_callback scan_cb;
31 K_SEM_DEFINE(scan_lock, 0, 1);
32 
33 static bool expected_association_permitted_bit;
34 
35 #define EXPECTED_COORDINATOR_LQI           15U
36 
37 #define EXPECTED_COORDINATOR_PAN_LE        0xcd, 0xab
38 #define EXPECTED_COORDINATOR_PAN_CPU_ORDER 0xabcd
39 #define EXPECTED_COORDINATOR_PAN_STR       "43981"
40 
41 #define EXPECTED_COORDINATOR_ADDR_LE       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
42 #define EXPECTED_COORDINATOR_ADDR_BE       0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08
43 #define EXPECTED_COORDINATOR_ADDR_STR      "0f:0e:0d:0c:0b:0a:09:08"
44 #define EXPECTED_COORDINATOR_SHORT_ADDR    0xbbbb
45 
46 #define EXPECTED_ENDDEVICE_EXT_ADDR_LE     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
47 #define EXPECTED_ENDDEVICE_EXT_ADDR_STR    "08:07:06:05:04:03:02:01"
48 #define EXPECTED_ENDDEVICE_SHORT_ADDR      0xaaaa
49 
50 #define EXPECTED_PAYLOAD_DATA EXPECTED_ENDDEVICE_EXT_ADDR_LE
51 #define EXPECTED_PAYLOAD_LEN  8
52 
scan_result_cb(struct net_mgmt_event_callback * cb,uint32_t mgmt_event,struct net_if * iface)53 static void scan_result_cb(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
54 			   struct net_if *iface)
55 {
56 	struct ieee802154_context *ctx = net_if_l2_data(iface);
57 	struct ieee802154_req_params *scan_ctx = ctx->scan_ctx;
58 	uint8_t expected_coordinator_address[] = {EXPECTED_COORDINATOR_ADDR_BE};
59 	uint8_t expected_payload_data[] = {EXPECTED_PAYLOAD_DATA};
60 
61 	/* No need for scan_ctx locking as we should execute exclusively. */
62 
63 	zassert_not_null(scan_ctx);
64 	zassert_equal(scan_ctx->pan_id, EXPECTED_COORDINATOR_PAN_CPU_ORDER,
65 		      "Scan did not receive correct PAN id.");
66 	zassert_equal(scan_ctx->len, IEEE802154_EXT_ADDR_LENGTH,
67 		      "Scan did not receive correct co-ordinator address length.");
68 	zassert_mem_equal(scan_ctx->addr, expected_coordinator_address, IEEE802154_EXT_ADDR_LENGTH);
69 	zassert_equal(scan_ctx->lqi, EXPECTED_COORDINATOR_LQI,
70 		      "Scan did not receive correct link quality indicator.");
71 	zassert_equal(scan_ctx->association_permitted, expected_association_permitted_bit,
72 		      "Scan did not set the association permit bit correctly.");
73 
74 	zassert_equal(scan_ctx->beacon_payload_len, EXPECTED_PAYLOAD_LEN,
75 		      "Scan did not include the payload");
76 	zassert_mem_equal(scan_ctx->beacon_payload, expected_payload_data, EXPECTED_PAYLOAD_LEN);
77 
78 	k_sem_give(&scan_lock);
79 }
80 
test_beacon_request(struct ieee802154_mpdu * mpdu)81 static void test_beacon_request(struct ieee802154_mpdu *mpdu)
82 {
83 	struct ieee802154_command *cmd = mpdu->command;
84 
85 	zassert_equal(mpdu->payload_length, 1U, "Beacon request: invalid payload length.");
86 	zassert_equal(cmd->cfi, IEEE802154_CFI_BEACON_REQUEST, "Not a beacon request.");
87 	zassert_equal(mpdu->mhr.fs->fc.dst_addr_mode, IEEE802154_ADDR_MODE_SHORT,
88 		      "Beacon request: invalid destination address mode.");
89 	zassert_equal(mpdu->mhr.dst_addr->plain.addr.short_addr, IEEE802154_BROADCAST_ADDRESS,
90 		      "Beacon request: destination address should be broadcast address.");
91 	zassert_equal(mpdu->mhr.dst_addr->plain.pan_id, IEEE802154_BROADCAST_PAN_ID,
92 		      "Beacon request: destination PAN should be broadcast PAN.");
93 }
94 
test_association_request(struct ieee802154_mpdu * mpdu)95 static void test_association_request(struct ieee802154_mpdu *mpdu)
96 {
97 	struct ieee802154_command *cmd = mpdu->command;
98 
99 	zassert_equal(
100 		mpdu->mhr.fs->fc.frame_version, IEEE802154_VERSION_802154_2006,
101 		"Association Request: currently only IEEE 802.15.4 2006 frame version supported.");
102 	zassert_equal(mpdu->mhr.fs->fc.frame_type, IEEE802154_FRAME_TYPE_MAC_COMMAND,
103 		      "Association Request: should be a MAC command.");
104 	zassert_equal(mpdu->mhr.fs->fc.ar, true, "Association Request: must request ACK.");
105 	zassert_equal(mpdu->payload_length, 1U + IEEE802154_CMD_ASSOC_REQ_LENGTH);
106 
107 	zassert_equal(cmd->cfi, IEEE802154_CFI_ASSOCIATION_REQUEST,
108 		      "Association Request: unexpected CFI.");
109 	zassert_equal(cmd->assoc_req.ci.alloc_addr, true,
110 		      "Association Request: should allocate short address.");
111 	zassert_equal(cmd->assoc_req.ci.association_type, false,
112 		      "Association Request: fast association is not supported.");
113 }
114 
test_disassociation_notification(struct ieee802154_mpdu * mpdu)115 static void test_disassociation_notification(struct ieee802154_mpdu *mpdu)
116 {
117 	struct ieee802154_command *cmd = mpdu->command;
118 
119 	zassert_equal(mpdu->mhr.fs->fc.frame_version, IEEE802154_VERSION_802154_2006,
120 		      "Disassociation Notification: currently only IEEE 802.15.4 2006 frame "
121 		      "version supported.");
122 	zassert_equal(mpdu->mhr.fs->fc.frame_type, IEEE802154_FRAME_TYPE_MAC_COMMAND,
123 		      "Disassociation Notification: should be a MAC command.");
124 	zassert_equal(mpdu->mhr.fs->fc.ar, true, "Disassociation Notification: must request ACK.");
125 	zassert_equal(mpdu->payload_length, 1U + IEEE802154_CMD_DISASSOC_NOTE_LENGTH);
126 
127 	zassert_equal(cmd->cfi, IEEE802154_CFI_DISASSOCIATION_NOTIFICATION,
128 		      "Disassociation Notification: unexpected CFI.");
129 	zassert_equal(
130 		cmd->disassoc_note.reason, IEEE802154_DRF_DEVICE_WISH,
131 		"Disassociation Notification: notification should be initiated by the enddevice.");
132 }
133 
test_scan_shell_cmd(void)134 static void test_scan_shell_cmd(void)
135 {
136 	struct ieee802154_mpdu mpdu = {0};
137 	int ret;
138 
139 	/* The beacon placed into the RX queue will be received and handled as
140 	 * soon as this command yields waiting for beacons.
141 	 * Scan should be as short as possible, because after 1 second an IPv6
142 	 * Router Solicitation package will be placed into the TX queue
143 	 */
144 	ret = shell_execute_cmd(NULL, "ieee802154 scan active 11 10");
145 	zassert_equal(0, ret, "Active scan failed: %d", ret);
146 
147 	zassert_equal(0, k_sem_take(&scan_lock, K_NO_WAIT), "Active scan: did not receive beacon.");
148 
149 	zassert_not_null(current_pkt);
150 
151 	if (!ieee802154_validate_frame(net_pkt_data(current_pkt), net_pkt_get_len(current_pkt),
152 				       &mpdu)) {
153 		NET_ERR("*** Could not parse beacon request.");
154 		ztest_test_fail();
155 		goto release_frag;
156 	}
157 
158 	test_beacon_request(&mpdu);
159 
160 release_frag:
161 	net_pkt_frag_unref(current_pkt->frags);
162 	current_pkt->frags = NULL;
163 }
164 
test_associate_shell_cmd(struct ieee802154_context * ctx)165 static void test_associate_shell_cmd(struct ieee802154_context *ctx)
166 {
167 	uint8_t expected_coord_addr_le[] = {EXPECTED_COORDINATOR_ADDR_LE};
168 	struct ieee802154_mpdu mpdu = {0};
169 	struct net_buf *assoc_req;
170 	int ret;
171 
172 	/* The association response placed into the RX queue will be received and
173 	 * handled as soon as this command yields waiting for a response.
174 	 */
175 	ret = shell_execute_cmd(NULL, "ieee802154 associate " EXPECTED_COORDINATOR_PAN_STR
176 				      " " EXPECTED_COORDINATOR_ADDR_STR);
177 	zassert_equal(0, ret, "Association failed: %d", ret);
178 
179 	/* Test that we were associated. */
180 	zassert_equal(ctx->pan_id, EXPECTED_COORDINATOR_PAN_CPU_ORDER,
181 		      "Association: did not get associated to the expected PAN.");
182 	zassert_equal(ctx->short_addr, EXPECTED_ENDDEVICE_SHORT_ADDR,
183 		      "Association: did not get the expected short address asigned.");
184 	zassert_equal(ctx->coord_short_addr, IEEE802154_NO_SHORT_ADDRESS_ASSIGNED,
185 		      "Association: co-ordinator should not use short address.");
186 	zassert_mem_equal(
187 		ctx->coord_ext_addr, expected_coord_addr_le, sizeof(ctx->coord_ext_addr),
188 		"Association: did not get associated co-ordinator by the expected coordinator.");
189 
190 	/* Test the association request that should have been sent out. */
191 	zassert_not_null(current_pkt);
192 	assoc_req = current_pkt->frags;
193 	zassert_not_null(assoc_req);
194 
195 	if (!ieee802154_validate_frame(assoc_req->data, assoc_req->len, &mpdu)) {
196 		NET_ERR("*** Could not parse association request.");
197 		ztest_test_fail();
198 		goto release_frag;
199 	}
200 
201 	test_association_request(&mpdu);
202 
203 release_frag:
204 	net_pkt_frag_unref(current_pkt->frags);
205 	current_pkt->frags = NULL;
206 }
207 
create_and_receive_packet(uint8_t * beacon_pkt,size_t length)208 static int create_and_receive_packet(uint8_t *beacon_pkt, size_t length)
209 {
210 	struct net_pkt *pkt;
211 
212 	pkt = net_pkt_rx_alloc_with_buffer(net_iface, length, AF_UNSPEC, 0, K_FOREVER);
213 	if (!pkt) {
214 		NET_ERR("*** No buffer to allocate");
215 		return -1;
216 	}
217 
218 	net_pkt_set_ieee802154_lqi(pkt, EXPECTED_COORDINATOR_LQI);
219 	net_buf_add_mem(pkt->buffer, beacon_pkt, length);
220 
221 	/* The packet will be placed in the RX queue but not yet handled. */
222 	if (net_recv_data(net_iface, pkt) < 0) {
223 		NET_ERR("Recv data failed");
224 		net_pkt_unref(pkt);
225 		return -1;
226 	}
227 	return 0;
228 }
229 
ZTEST(ieee802154_l2_shell,test_active_scan)230 ZTEST(ieee802154_l2_shell, test_active_scan)
231 {
232 	uint8_t beacon_pkt[] = {
233 		0x00, 0xd0, /* FCF */
234 		0x11, /* Sequence Number: 17 */
235 		EXPECTED_COORDINATOR_PAN_LE, /* Source PAN */
236 		EXPECTED_COORDINATOR_ADDR_LE, /* Extended Source Address */
237 		0x00, 0xc0, /* Superframe Specification: PAN coordinator + association permitted */
238 		0x00, /* GTS */
239 		0x00, /* Pending Addresses */
240 		EXPECTED_PAYLOAD_DATA /* Layer 3 payload */
241 	};
242 
243 	net_mgmt_init_event_callback(&scan_cb, scan_result_cb, NET_EVENT_IEEE802154_SCAN_RESULT);
244 	net_mgmt_add_event_callback(&scan_cb);
245 
246 	expected_association_permitted_bit = true;
247 
248 	if (create_and_receive_packet(beacon_pkt, sizeof(beacon_pkt)) < 0) {
249 		goto fail;
250 	}
251 
252 	test_scan_shell_cmd();
253 
254 	/* disable the association permit flag */
255 	beacon_pkt[14] = 0x40;
256 	expected_association_permitted_bit = false;
257 
258 	if (create_and_receive_packet(beacon_pkt, sizeof(beacon_pkt)) < 0) {
259 		goto fail;
260 	}
261 
262 	test_scan_shell_cmd();
263 
264 	net_mgmt_del_event_callback(&scan_cb);
265 	return;
266 
267 fail:
268 	ztest_test_fail();
269 }
270 
ZTEST(ieee802154_l2_shell,test_associate)271 ZTEST(ieee802154_l2_shell, test_associate)
272 {
273 	uint8_t coord_addr_le[] = {EXPECTED_COORDINATOR_ADDR_LE};
274 	struct ieee802154_context *ctx = net_if_l2_data(net_iface);
275 	struct ieee802154_frame_params params = {
276 		.dst = {
277 			.len = IEEE802154_EXT_ADDR_LENGTH,
278 			.pan_id = EXPECTED_COORDINATOR_PAN_CPU_ORDER,
279 		}};
280 	struct ieee802154_command *cmd;
281 	struct net_pkt *pkt;
282 
283 	sys_memcpy_swap(params.dst.ext_addr, ctx->ext_addr, sizeof(params.dst.ext_addr));
284 
285 	/* Simulate a packet from the coordinator. */
286 	memcpy(ctx->ext_addr, coord_addr_le, sizeof(ctx->ext_addr));
287 
288 	pkt = ieee802154_create_mac_cmd_frame(net_iface, IEEE802154_CFI_ASSOCIATION_RESPONSE,
289 					      &params);
290 	if (!pkt) {
291 		NET_ERR("*** Could not create association response");
292 		goto fail;
293 	}
294 
295 	cmd = ieee802154_get_mac_command(pkt);
296 	cmd->assoc_res.short_addr = sys_cpu_to_le16(EXPECTED_ENDDEVICE_SHORT_ADDR);
297 	cmd->assoc_res.status = IEEE802154_ASF_SUCCESSFUL;
298 	ieee802154_mac_cmd_finalize(pkt, IEEE802154_CFI_ASSOCIATION_RESPONSE);
299 
300 	/* The packet will be placed in the RX queue but not yet handled. */
301 	if (net_recv_data(net_iface, pkt) < 0) {
302 		NET_ERR("Recv assoc resp pkt failed");
303 		net_pkt_unref(pkt);
304 		goto fail;
305 	}
306 
307 	/* Restore the end device's extended address. */
308 	sys_memcpy_swap(ctx->ext_addr, params.dst.ext_addr, sizeof(ctx->ext_addr));
309 
310 	test_associate_shell_cmd(ctx);
311 	return;
312 
313 fail:
314 	sys_memcpy_swap(ctx->ext_addr, params.dst.ext_addr, sizeof(ctx->ext_addr));
315 	ztest_test_fail();
316 }
317 
ZTEST(ieee802154_l2_shell,test_initiate_disassociation_from_enddevice)318 ZTEST(ieee802154_l2_shell, test_initiate_disassociation_from_enddevice)
319 {
320 	uint8_t expected_coord_addr_le[] = {EXPECTED_COORDINATOR_ADDR_LE};
321 	uint8_t empty_coord_addr[IEEE802154_EXT_ADDR_LENGTH] = {0};
322 	struct ieee802154_context *ctx = net_if_l2_data(net_iface);
323 	uint8_t mock_ext_addr_le[IEEE802154_EXT_ADDR_LENGTH];
324 	struct ieee802154_mpdu mpdu = {0};
325 	int ret;
326 
327 	/* Simulate an associated device. */
328 	ctx->pan_id = EXPECTED_COORDINATOR_PAN_CPU_ORDER;
329 	ctx->short_addr = EXPECTED_ENDDEVICE_SHORT_ADDR;
330 	ctx->coord_short_addr = EXPECTED_COORDINATOR_SHORT_ADDR;
331 	memcpy(ctx->coord_ext_addr, expected_coord_addr_le, sizeof(ctx->coord_ext_addr));
332 
333 	ret = shell_execute_cmd(NULL, "ieee802154 disassociate");
334 	zassert_equal(0, ret, "Initiating disassociation from the enddevice failed: %d", ret);
335 
336 	/* Ensure we've been disassociated. */
337 	zassert_mem_equal(ctx->coord_ext_addr, empty_coord_addr, sizeof(ctx->coord_ext_addr),
338 			  "Disassociation: coordinator address should be unset.");
339 	zassert_equal(ctx->pan_id, IEEE802154_PAN_ID_NOT_ASSOCIATED,
340 		      "Disassociation: PAN should be unset.");
341 	zassert_equal(ctx->short_addr, IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED,
342 		      "Disassociation: Short addr should be unset.");
343 	sys_memcpy_swap(mock_ext_addr_le, mock_ext_addr_be, sizeof(mock_ext_addr_le));
344 	zassert_mem_equal(ctx->ext_addr, mock_ext_addr_le, sizeof(ctx->ext_addr),
345 			  "Disassociation: Ext addr should be unaffected.");
346 
347 	zassert_not_null(current_pkt);
348 
349 	if (!ieee802154_validate_frame(net_pkt_data(current_pkt), net_pkt_get_len(current_pkt),
350 				       &mpdu)) {
351 		NET_ERR("*** Could not parse disassociation notification.");
352 		ztest_test_fail();
353 		goto release_frag;
354 	}
355 
356 	test_disassociation_notification(&mpdu);
357 
358 release_frag:
359 	net_pkt_frag_unref(current_pkt->frags);
360 	current_pkt->frags = NULL;
361 }
362 
ZTEST(ieee802154_l2_shell,test_initiate_disassociation_from_coordinator)363 ZTEST(ieee802154_l2_shell, test_initiate_disassociation_from_coordinator)
364 {
365 	uint8_t expected_coord_addr_le[] = {EXPECTED_COORDINATOR_ADDR_LE};
366 	uint8_t empty_coord_addr[IEEE802154_EXT_ADDR_LENGTH] = {0};
367 	struct ieee802154_context *ctx = net_if_l2_data(net_iface);
368 	uint8_t mock_ext_addr_le[IEEE802154_EXT_ADDR_LENGTH];
369 	struct ieee802154_frame_params params = {
370 		.dst = {
371 			.len = IEEE802154_EXT_ADDR_LENGTH,
372 			.pan_id = EXPECTED_COORDINATOR_PAN_CPU_ORDER,
373 		}};
374 	struct ieee802154_command *cmd;
375 	struct net_pkt *pkt;
376 
377 	/* Simulate an associated device. */
378 
379 	sys_memcpy_swap(params.dst.ext_addr, ctx->ext_addr, sizeof(params.dst.ext_addr));
380 
381 	/* Simulate a packet from the coordinator. */
382 	ctx->device_role = IEEE802154_DEVICE_ROLE_PAN_COORDINATOR;
383 	ctx->pan_id = EXPECTED_COORDINATOR_PAN_CPU_ORDER;
384 	ctx->short_addr = EXPECTED_COORDINATOR_SHORT_ADDR;
385 	memcpy(ctx->ext_addr, expected_coord_addr_le, sizeof(ctx->ext_addr));
386 
387 	/* Create and send an incoming disassociation notification. */
388 	pkt = ieee802154_create_mac_cmd_frame(net_iface, IEEE802154_CFI_DISASSOCIATION_NOTIFICATION,
389 					      &params);
390 	if (!pkt) {
391 		NET_ERR("*** Could not create association response");
392 		goto fail;
393 	}
394 
395 	cmd = ieee802154_get_mac_command(pkt);
396 	cmd->disassoc_note.reason = IEEE802154_DRF_COORDINATOR_WISH;
397 	ieee802154_mac_cmd_finalize(pkt, IEEE802154_CFI_DISASSOCIATION_NOTIFICATION);
398 
399 	/* Restore the end device's state and simulate an associated device. */
400 	ctx->device_role = IEEE802154_DEVICE_ROLE_ENDDEVICE;
401 	ctx->short_addr = EXPECTED_ENDDEVICE_SHORT_ADDR;
402 	sys_memcpy_swap(ctx->ext_addr, params.dst.ext_addr, sizeof(ctx->ext_addr));
403 	ctx->coord_short_addr = EXPECTED_COORDINATOR_SHORT_ADDR;
404 	memcpy(ctx->coord_ext_addr, expected_coord_addr_le, sizeof(ctx->coord_ext_addr));
405 
406 	if (net_recv_data(net_iface, pkt) < 0) {
407 		NET_ERR("Recv assoc resp pkt failed");
408 		net_pkt_unref(pkt);
409 		goto fail;
410 	}
411 
412 	/* We need to yield, so that the packet is actually being received from the RX thread. */
413 	k_yield();
414 
415 	/* We should have received an ACK packet. */
416 	zassert_not_null(current_pkt);
417 	zassert_not_null(current_pkt->frags);
418 	zassert_equal(net_pkt_get_len(current_pkt), IEEE802154_ACK_PKT_LENGTH,
419 		      "Did not receive the expected ACK packet.");
420 	net_pkt_frag_unref(current_pkt->frags);
421 	current_pkt->frags = NULL;
422 
423 	/* Ensure we've been disassociated. */
424 	zassert_mem_equal(ctx->coord_ext_addr, empty_coord_addr, sizeof(ctx->coord_ext_addr),
425 			  "Disassociation: coordinator address should be unset.");
426 	zassert_equal(ctx->pan_id, IEEE802154_PAN_ID_NOT_ASSOCIATED,
427 		      "Disassociation: PAN should be unset.");
428 	zassert_equal(ctx->short_addr, IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED,
429 		      "Disassociation: Short addr should be unset.");
430 	sys_memcpy_swap(mock_ext_addr_le, mock_ext_addr_be, sizeof(mock_ext_addr_le));
431 	zassert_mem_equal(ctx->ext_addr, mock_ext_addr_le, sizeof(ctx->ext_addr),
432 			  "Disassociation: Ext addr should be unaffected.");
433 
434 	return;
435 
436 fail:
437 	sys_memcpy_swap(ctx->ext_addr, params.dst.ext_addr, sizeof(ctx->ext_addr));
438 	ztest_test_fail();
439 }
440 
ZTEST(ieee802154_l2_shell,test_set_ext_addr)441 ZTEST(ieee802154_l2_shell, test_set_ext_addr)
442 {
443 	uint8_t expected_ext_addr_le[] = {EXPECTED_ENDDEVICE_EXT_ADDR_LE};
444 	struct ieee802154_context *ctx = net_if_l2_data(net_iface);
445 	uint8_t initial_ext_addr_le[sizeof(mock_ext_addr_be)];
446 	int ret;
447 
448 	sys_memcpy_swap(initial_ext_addr_le, mock_ext_addr_be, sizeof(initial_ext_addr_le));
449 	zassert_equal(ctx->pan_id, IEEE802154_PAN_ID_NOT_ASSOCIATED,
450 		      "Setting Ext Addr: PAN should not be set initially.");
451 	zassert_equal(ctx->short_addr, IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED,
452 		      "Setting Ext Addr: Short addr should not be set initially.");
453 	zassert_mem_equal(ctx->ext_addr, initial_ext_addr_le, sizeof(ctx->coord_ext_addr),
454 			  "Setting Ext Addr: Ext addr should be the mock addr initially.");
455 
456 	ret = shell_execute_cmd(NULL, "ieee802154 set_ext_addr " EXPECTED_ENDDEVICE_EXT_ADDR_STR);
457 	zassert_equal(0, ret, "Setting the external address failed: %d", ret);
458 
459 	zassert_mem_equal(
460 		ctx->ext_addr, expected_ext_addr_le, sizeof(ctx->coord_ext_addr),
461 		"Setting Ext Addr: failed.");
462 
463 	memcpy(ctx->ext_addr, initial_ext_addr_le, sizeof(ctx->ext_addr));
464 }
465 
reset_fake_driver(void * test_fixture)466 static void reset_fake_driver(void *test_fixture)
467 {
468 	struct ieee802154_context *ctx;
469 
470 	ARG_UNUSED(test_fixture);
471 
472 	__ASSERT_NO_MSG(net_iface);
473 
474 	/* Set initial conditions. */
475 	ctx = net_if_l2_data(net_iface);
476 	ctx->pan_id = IEEE802154_PAN_ID_NOT_ASSOCIATED;
477 	ctx->short_addr = IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED;
478 	ctx->coord_short_addr = IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED;
479 	memset(ctx->coord_ext_addr, 0, sizeof(ctx->coord_ext_addr));
480 }
481 
test_setup(void)482 static void *test_setup(void)
483 {
484 	const struct device *dev = device_get_binding("fake_ieee802154");
485 
486 	k_sem_reset(&driver_lock);
487 
488 	if (!dev) {
489 		NET_ERR("*** Could not get fake device");
490 		return NULL;
491 	}
492 
493 	net_iface = net_if_lookup_by_dev(dev);
494 	if (!net_iface) {
495 		NET_ERR("*** Could not get fake iface");
496 		return NULL;
497 	}
498 
499 	NET_INFO("Fake IEEE 802.15.4 network interface ready");
500 
501 	current_pkt = net_pkt_rx_alloc(K_FOREVER);
502 	if (!current_pkt) {
503 		NET_ERR("*** No buffer to allocate");
504 		return false;
505 	}
506 
507 	return NULL;
508 }
509 
test_teardown(void * test_fixture)510 static void test_teardown(void *test_fixture)
511 {
512 	ARG_UNUSED(test_fixture);
513 
514 	net_pkt_unref(current_pkt);
515 	current_pkt = NULL;
516 }
517 
518 ZTEST_SUITE(ieee802154_l2_shell, NULL, test_setup, reset_fake_driver, reset_fake_driver,
519 	    test_teardown);
520