1 /*
2 * Copyright (c) 2016 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(net_ieee802154_test, LOG_LEVEL_DBG);
9
10 #include <zephyr/kernel.h>
11 #include <zephyr/ztest.h>
12
13
14 #include <zephyr/crypto/crypto.h>
15 #include <zephyr/net/ethernet.h>
16 #include <zephyr/net/ieee802154.h>
17 #include <zephyr/net/ieee802154_mgmt.h>
18 #include <zephyr/net/ieee802154_radio.h>
19 #include <zephyr/net/net_core.h>
20 #include <zephyr/net/net_ip.h>
21 #include <zephyr/net/net_pkt.h>
22 #include <zephyr/net/socket.h>
23
24 #include "net_private.h"
25 #include <ieee802154_frame.h>
26 #include <ieee802154_priv.h>
27 #include <ipv6.h>
28
29 struct ieee802154_pkt_test {
30 char *name;
31 struct in6_addr src;
32 struct in6_addr dst;
33 uint8_t *pkt;
34 uint8_t sequence;
35 uint8_t length;
36 uint8_t payload_length;
37 struct {
38 struct ieee802154_fcf_seq *fc_seq;
39 struct ieee802154_address_field *dst_addr;
40 struct ieee802154_address_field *src_addr;
41 } mhr_check;
42 };
43
44 /* Sample NS packet with extended address. */
45 uint8_t ns_pkt[] = {
46 0x41, 0xd8, /* FCF */
47 0x45, /* Sequence Number */
48 0xcd, 0xab, /* PAN ID */
49 0xff, 0xff, /* Destination Address (Broadcast) */
50 0xc2, 0xa3, 0x9e, 0x00, 0x00, 0x4b, 0x12, 0x00, /* Source Address */
51 0x7b, 0x09, /* IPHC Header */
52 0x3a, /* Next Header: ICMPv6 */
53 0x20, 0x01, 0xdb, 0x08, 0x00, 0x00, 0x00, 0x00, /* IPv6 Source Address */
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
55 0x02, 0x01, 0xff, 0x00, 0x00, 0x01, /* IPv6 Destination Address */
56 0x87, /* ICMPv6 Type: Neighbour Solicitation */
57 0x00, /* Code */
58 0x91, 0x11, /* Checksum */
59 0x00, 0x00, 0x00, 0x00, /* Reserved */
60 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Target Address */
61 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x01,
62 0x01, /* ICMPv6 Option: Source LL Address */
63 0x02, /* Length */
64 0x00, 0x12, 0x4b, 0x00, 0x00, 0x9e, 0xa3, 0xc2, /* LL Address */
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* Padding */
66 };
67
68 struct ieee802154_pkt_test test_ns_pkt = {
69 .name = "NS frame",
70 .src = { { { 0x20, 0x01, 0xdb, 0x08, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } },
72 .dst = { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x01 } } },
74 .pkt = ns_pkt,
75 .sequence = 69U,
76 .length = sizeof(ns_pkt),
77 .payload_length = 65U,
78 .mhr_check = {
79 .fc_seq = (struct ieee802154_fcf_seq *)ns_pkt,
80 .dst_addr = (struct ieee802154_address_field *)(ns_pkt + 3),
81 .src_addr = (struct ieee802154_address_field *)(ns_pkt + 7),
82 }};
83
84 uint8_t ack_pkt[] = {
85 0x02, 0x10, /* FCF */
86 0x16 /* Sequence Number */
87 };
88
89 struct ieee802154_pkt_test test_ack_pkt = {
90 .name = "ACK frame",
91 .sequence = 22U,
92 .pkt = ack_pkt,
93 .length = sizeof(ack_pkt),
94 .payload_length = 0U,
95 .mhr_check = {
96 .fc_seq = (struct ieee802154_fcf_seq *)ack_pkt,
97 .dst_addr = NULL,
98 .src_addr = NULL,
99 }};
100
101 uint8_t beacon_pkt[] = {
102 0x00, 0xd0, /* FCF */
103 0x11, /* Sequence Number */
104 0xcd, 0xab, /* Source PAN ID */
105 0xc2, 0xa3, 0x9e, 0x00, 0x00, 0x4b, 0x12, 0x00, /* Source Address */
106 0x00, 0x00, /* Superframe Specification */
107 0x00, /* GTS */
108 0x00, /* Pending Addresses */
109 0x00, 0x00 /* Payload */
110 };
111
112 struct ieee802154_pkt_test test_beacon_pkt = {
113 .name = "Empty beacon frame",
114 .sequence = 17U,
115 .pkt = beacon_pkt,
116 .length = sizeof(beacon_pkt),
117 .payload_length = 6U,
118 .mhr_check = {
119 .fc_seq = (struct ieee802154_fcf_seq *)beacon_pkt,
120 .dst_addr = NULL,
121 .src_addr = (struct ieee802154_address_field *)(beacon_pkt + 3),
122 }};
123
124 uint8_t sec_data_pkt[] = {
125 0x49, 0xd8, /* FCF */
126 0x45, /* Sequence Number */
127 0xcd, 0xab, /* Destination PAN */
128 0xff, 0xff, /* Destination Address */
129 0xc2, 0xa3, 0x9e, 0x00, 0x00, 0x4b, 0x12, 0x00, /* Source Address */
130 0x07, /* Security Control Field */
131 0x03, 0x00, 0x00, 0x00, /* Frame Counter */
132 0x98, 0x49, 0x1f, 0x57, /* Encrypted Payload */
133 0x99, 0xf9, 0x10, 0x5e, 0x5b, 0x8c, 0x31, 0x0b, /* MIC (128 bit) */
134 0xa1, 0x70, 0x99, 0x14, 0x0a, 0x6a, 0x38, 0x47,
135 };
136
137 struct ieee802154_pkt_test test_sec_data_pkt = {
138 .name = "Secured data frame",
139 .sequence = 69U,
140 .pkt = sec_data_pkt,
141 .length = sizeof(sec_data_pkt),
142 .payload_length = 4U /* encrypted payload */ + 16U /* MIC */,
143 .mhr_check = {
144 .fc_seq = (struct ieee802154_fcf_seq *)sec_data_pkt,
145 .dst_addr = (struct ieee802154_address_field *)(sec_data_pkt + 3),
146 .src_addr = (struct ieee802154_address_field *)(sec_data_pkt + 7),
147 }};
148
149 /* Construct raw packet payload, length and FCS gets added in the radio driver,
150 * see https://github.com/linux-wpan/wpan-tools/blob/master/examples/af_packet_tx.c
151 */
152 uint8_t raw_payload[] = {
153 0x01, 0xc8, /* FCF */
154 0x8b, /* Sequence number */
155 0xff, 0xff, /* Destination PAN ID 0xffff */
156 0x02, 0x00, /* Destination short address 0x0002 */
157 0x23, 0x00, /* Source PAN ID 0x0023 */
158 0x60, 0xe2, 0x16, 0x21,
159 0x1c, 0x4a, 0xc2, 0xae, /* Source extended address ae:c2:4a:1c:21:16:e2:60 */
160 0xAA, 0xBB, 0xCC, /* MAC Payload */
161 };
162 #define RAW_MAC_PAYLOAD_START_INDEX 17
163 #define RAW_MAC_PAYLOAD_LENGTH 3
164
165 #define MOCK_PAN_ID 0xabcd
166
167 extern struct net_pkt *current_pkt;
168 extern struct k_sem driver_lock;
169
170 static struct net_if *net_iface;
171
pkt_hexdump(uint8_t * pkt,uint8_t length)172 static void pkt_hexdump(uint8_t *pkt, uint8_t length)
173 {
174 int i;
175
176 printk(" -> Packet content:\n");
177
178 for (i = 0; i < length;) {
179 int j;
180
181 printk("\t");
182
183 for (j = 0; j < 10 && i < length; j++, i++) {
184 printk("%02x ", *pkt);
185 pkt++;
186 }
187
188 printk("\n");
189 }
190 }
191
ieee_addr_hexdump(uint8_t * addr,uint8_t length)192 static void ieee_addr_hexdump(uint8_t *addr, uint8_t length)
193 {
194 int i;
195
196 printk(" -> IEEE 802.15.4 Address: ");
197
198 for (i = 0; i < length-1; i++) {
199 printk("%02x:", *addr);
200 addr++;
201 }
202
203 printk("%02x\n", *addr);
204 }
205
disassociate(struct net_if * iface,struct ieee802154_context * ctx)206 static int disassociate(struct net_if *iface, struct ieee802154_context *ctx)
207 {
208 uint16_t short_addr_not_associated = IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED;
209 int ret;
210
211 if (ctx->short_addr == IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED) {
212 return 0;
213 }
214
215 ret = net_mgmt(NET_REQUEST_IEEE802154_SET_SHORT_ADDR, iface,
216 &short_addr_not_associated,
217 sizeof(short_addr_not_associated));
218 if (ret) {
219 NET_ERR("*** Failed to %s.", __func__);
220 return ret;
221 }
222
223 return 0;
224 }
225
associate(struct net_if * iface,struct ieee802154_context * ctx,uint16_t short_addr)226 static int associate(struct net_if *iface, struct ieee802154_context *ctx, uint16_t short_addr)
227 {
228 uint16_t mock_pan_id = MOCK_PAN_ID;
229 int ret;
230
231 if (ctx->short_addr == short_addr) {
232 return -EALREADY;
233 }
234
235 ret = net_mgmt(NET_REQUEST_IEEE802154_SET_PAN_ID, iface, &mock_pan_id,
236 sizeof(mock_pan_id));
237 if (ret) {
238 NET_ERR("*** Failed to set PAN ID in %s.", __func__);
239 return ret;
240 }
241
242 ret = net_mgmt(NET_REQUEST_IEEE802154_SET_SHORT_ADDR, iface, &short_addr,
243 sizeof(short_addr));
244 if (ret) {
245 NET_ERR("*** Failed to set short addr in %s.", __func__);
246 return ret;
247 }
248
249 return 0;
250 }
251
set_up_short_addr(struct net_if * iface,struct ieee802154_context * ctx)252 static int set_up_short_addr(struct net_if *iface, struct ieee802154_context *ctx)
253 {
254 const uint16_t mock_short_addr = 0x5678;
255 int ret;
256
257 ret = disassociate(iface, ctx);
258 if (ret) {
259 return ret;
260 }
261
262 ret = associate(iface, ctx, mock_short_addr);
263 if (ret) {
264 return ret;
265 }
266
267 return 0;
268 }
269
tear_down_short_addr(struct net_if * iface,struct ieee802154_context * ctx)270 static int tear_down_short_addr(struct net_if *iface, struct ieee802154_context *ctx)
271 {
272 uint16_t no_short_addr_assigned = IEEE802154_NO_SHORT_ADDRESS_ASSIGNED;
273 int ret;
274
275 if (ctx->linkaddr.len != IEEE802154_SHORT_ADDR_LENGTH) {
276 /* nothing to do */
277 return 0;
278 }
279
280 ret = disassociate(iface, ctx);
281 if (ret) {
282 return ret;
283 }
284
285 ret = associate(iface, ctx, no_short_addr_assigned);
286 if (ret) {
287 return ret;
288 }
289
290 return 0;
291 }
292
get_data_pkt_with_ar(void)293 static struct net_pkt *get_data_pkt_with_ar(void)
294 {
295 /* Incoming IEEE 802.15.4 packet with payload header compression. */
296 static uint8_t data_pkt_with_ar[] = {
297 /* IEEE 802.15.4 MHR */
298 0x61, 0xd8, /* FCF with AR bit set */
299 0x16, /* Sequence */
300 0xcd, 0xab, /* Destination PAN */
301 0x78, 0x56, /* Destination Address */
302 0xc2, 0xa3, 0x9e, 0x00, 0x00, 0x4b, 0x12, 0x00, /* Source Address */
303 /* IEEE 802.15.4 MAC Payload */
304 0x7b, 0x39, /* IPHC header, SAM: compressed, DAM: 48-bits inline */
305 0x3a, /* Next header: ICMPv6 */
306 0x02, 0x01, 0xff, 0x4b, 0x12, 0x00, /* IPv6 Destination */
307 0x87, /* Type: NS */
308 0x00, /* Code*/
309 0xb7, 0x45, /* Checksum */
310 0x00, 0x00, 0x00, 0x00, /* Reserved */
311 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x14, 0xa6, 0x1c, 0x00, 0x4b,
312 0x12, 0x00, /* Target Address */
313 0x01, /* ICMPv6 Option: Source LL address */
314 0x02, /* Length */
315 0xe5, 0xac, 0xa1, 0x1c, 0x00, 0x4b, 0x12, 0x00, /* LL address */
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Padding */
317 };
318 struct net_pkt *pkt;
319
320 pkt = net_pkt_rx_alloc_with_buffer(net_iface, sizeof(data_pkt_with_ar), AF_UNSPEC, 0,
321 K_FOREVER);
322 if (!pkt) {
323 NET_ERR("*** No buffer to allocate");
324 return NULL;
325 }
326
327 net_buf_add_mem(pkt->frags, data_pkt_with_ar, sizeof(data_pkt_with_ar));
328
329 return pkt;
330 }
331
332 #ifdef CONFIG_NET_SOCKETS
set_up_security(uint8_t security_level)333 static bool set_up_security(uint8_t security_level)
334 {
335 struct ieee802154_context *ctx = net_if_l2_data(net_iface);
336 uint16_t saved_short_addr = ctx->short_addr;
337 struct ieee802154_security_params params;
338
339 if (security_level == IEEE802154_SECURITY_LEVEL_NONE) {
340 return true;
341 }
342
343 if (disassociate(net_iface, ctx) != 0) {
344 return false;
345 }
346
347 params = (struct ieee802154_security_params){
348 .key = {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
349 0xcc, 0xcd, 0xce, 0xcf},
350 .key_len = 16U,
351 .key_mode = IEEE802154_KEY_ID_MODE_IMPLICIT,
352 .level = security_level,
353 };
354
355 if (net_mgmt(NET_REQUEST_IEEE802154_SET_SECURITY_SETTINGS, net_iface, ¶ms,
356 sizeof(struct ieee802154_security_params))) {
357 NET_ERR("*** Failed to set security settings");
358 return false;
359 }
360
361 if (saved_short_addr != IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED &&
362 associate(net_iface, ctx, saved_short_addr) != 0) {
363 return false;
364 }
365
366 return true;
367 }
368
tear_down_security(void)369 static bool tear_down_security(void)
370 {
371 struct ieee802154_context *ctx = net_if_l2_data(net_iface);
372 uint16_t saved_short_addr = ctx->short_addr;
373 struct ieee802154_security_params params = {
374 .level = IEEE802154_SECURITY_LEVEL_NONE,
375 };
376
377 if (disassociate(net_iface, ctx) != 0) {
378 return false;
379 }
380
381 if (net_mgmt(NET_REQUEST_IEEE802154_SET_SECURITY_SETTINGS, net_iface, ¶ms,
382 sizeof(struct ieee802154_security_params))) {
383 NET_ERR("*** Failed to tear down security settings");
384 return false;
385 }
386
387 if (saved_short_addr != IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED &&
388 associate(net_iface, ctx, saved_short_addr) != 0) {
389 return false;
390 }
391
392 return true;
393 }
394
set_up_recv_socket(enum net_sock_type socket_type)395 static int set_up_recv_socket(enum net_sock_type socket_type)
396 {
397 struct sockaddr_ll socket_sll = {
398 .sll_ifindex = net_if_get_by_iface(net_iface),
399 .sll_family = AF_PACKET,
400 .sll_protocol = ETH_P_IEEE802154,
401 };
402 struct timeval timeo_optval = {
403 .tv_sec = 1,
404 .tv_usec = 0,
405 };
406 int fd;
407
408 fd = zsock_socket(AF_PACKET, socket_type, htons(ETH_P_IEEE802154));
409 if (fd < 0) {
410 NET_ERR("*** Failed to create recv socket : %d", errno);
411 return fd;
412 }
413
414 if (zsock_bind(fd, (const struct sockaddr *)&socket_sll, sizeof(struct sockaddr_ll))) {
415 NET_ERR("*** Failed to bind packet socket : %d", errno);
416 goto release_fd;
417 }
418
419 if (zsock_setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo_optval, sizeof(timeo_optval))) {
420 NET_ERR("*** Failed to set reception timeout on packet socket : %d", errno);
421 goto release_fd;
422 }
423
424 return fd;
425
426 release_fd:
427 zsock_close(fd);
428 return -EFAULT;
429 }
430 #endif /* CONFIG_NET_SOCKETS */
431
test_packet_parsing(struct ieee802154_pkt_test * t)432 static bool test_packet_parsing(struct ieee802154_pkt_test *t)
433 {
434 struct ieee802154_mpdu mpdu = {0};
435
436 NET_INFO("- Parsing packet 0x%p of frame %s", t->pkt, t->name);
437
438 if (!ieee802154_validate_frame(t->pkt, t->length, &mpdu)) {
439 NET_ERR("*** Could not validate frame %s", t->name);
440 return false;
441 }
442
443 if (mpdu.mhr.fs != t->mhr_check.fc_seq ||
444 mpdu.mhr.dst_addr != t->mhr_check.dst_addr ||
445 mpdu.mhr.src_addr != t->mhr_check.src_addr) {
446 NET_INFO("d: %p vs %p -- s: %p vs %p",
447 mpdu.mhr.dst_addr, t->mhr_check.dst_addr,
448 mpdu.mhr.src_addr, t->mhr_check.src_addr);
449 NET_ERR("*** Wrong MPDU information on frame %s", t->name);
450
451 return false;
452 }
453
454 if (mpdu.mhr.fs->sequence != t->sequence) {
455 NET_ERR("*** Invalid sequence number for frame %s", t->name);
456 return false;
457 }
458
459 if (mpdu.payload_length != t->payload_length) {
460 NET_ERR("*** Invalid payload length for frame %s", t->name);
461 return false;
462 }
463
464 return true;
465 }
466
test_ns_sending(struct ieee802154_pkt_test * t,bool with_short_addr)467 static bool test_ns_sending(struct ieee802154_pkt_test *t, bool with_short_addr)
468 {
469 struct ieee802154_context *ctx = net_if_l2_data(net_iface);
470 struct ieee802154_mpdu mpdu;
471 bool result = false;
472
473 NET_INFO("- Sending NS packet");
474
475 /* ensure reproducible results */
476 ctx->sequence = t->sequence;
477
478 if (with_short_addr && set_up_short_addr(net_iface, ctx)) {
479 goto out;
480 }
481
482 if (net_ipv6_send_ns(net_iface, NULL, &t->src, &t->dst, &t->dst, false)) {
483 NET_ERR("*** Could not create IPv6 NS packet");
484 tear_down_short_addr(net_iface, ctx);
485 goto out;
486 }
487
488 tear_down_short_addr(net_iface, ctx);
489
490 k_yield();
491 k_sem_take(&driver_lock, K_SECONDS(1));
492
493 if (!current_pkt->frags) {
494 NET_ERR("*** Could not send IPv6 NS packet");
495 goto out;
496 }
497
498 pkt_hexdump(net_pkt_data(current_pkt), net_pkt_get_len(current_pkt));
499
500 if (!with_short_addr) {
501 if (net_pkt_get_len(current_pkt) != t->length ||
502 memcmp(net_pkt_data(current_pkt), t->pkt, t->length)) {
503 NET_ERR("*** Sent packet deviates from expected packet");
504 goto release_frag;
505 }
506 }
507
508 if (!ieee802154_validate_frame(net_pkt_data(current_pkt),
509 net_pkt_get_len(current_pkt), &mpdu)) {
510 NET_ERR("*** Sent packet is not valid");
511 goto release_frag;
512 }
513
514 result = true;
515
516 release_frag:
517 net_pkt_frag_unref(current_pkt->frags);
518 current_pkt->frags = NULL;
519 out:
520 return result;
521 }
522
test_wait_for_ack(struct ieee802154_pkt_test * t)523 static bool test_wait_for_ack(struct ieee802154_pkt_test *t)
524 {
525 struct ieee802154_mpdu mpdu;
526 struct net_pkt *one_ack_pkt;
527 struct net_pkt *tx_pkt;
528 bool result = false;
529 bool ack_required;
530
531 NET_INFO("- Waiting for ACK reply when sending a data packet");
532
533 tx_pkt = get_data_pkt_with_ar();
534 if (!tx_pkt) {
535 goto out;
536 }
537
538 ack_required = ieee802154_prepare_for_ack(net_iface, tx_pkt, tx_pkt->frags);
539 if (!ack_required) {
540 NET_ERR("*** Expected AR flag to be set");
541 goto release_tx_pkt;
542 }
543
544 if (!ieee802154_validate_frame(net_pkt_data(tx_pkt), net_pkt_get_len(tx_pkt), &mpdu)) {
545 NET_ERR("*** Could not parse data pkt.");
546 goto release_tx_pkt;
547 }
548
549 one_ack_pkt = net_pkt_rx_alloc_with_buffer(net_iface, IEEE802154_ACK_PKT_LENGTH,
550 AF_UNSPEC, 0, K_FOREVER);
551 if (!one_ack_pkt) {
552 NET_ERR("*** Could not allocate ack pkt.");
553 goto release_tx_pkt;
554 }
555
556 if (!ieee802154_create_ack_frame(net_iface, one_ack_pkt, mpdu.mhr.fs->sequence)) {
557 NET_ERR("*** Could not create ack frame.");
558 goto release_tx_pkt;
559 }
560
561 pkt_hexdump(net_pkt_data(one_ack_pkt), net_pkt_get_len(one_ack_pkt));
562
563 if (ieee802154_handle_ack(net_iface, one_ack_pkt) != NET_OK) {
564 NET_ERR("*** Ack frame was not handled.");
565 goto release_ack_pkt;
566 }
567
568 if (ieee802154_wait_for_ack(net_iface, ack_required) != 0) {
569 NET_ERR("*** Ack frame was not recorded.");
570 goto release_ack_pkt;
571 }
572
573 result = true;
574
575 release_ack_pkt:
576 net_pkt_unref(one_ack_pkt);
577 release_tx_pkt:
578 net_pkt_unref(tx_pkt);
579 out:
580 return result;
581 }
582
test_packet_cloning_with_cb(void)583 static bool test_packet_cloning_with_cb(void)
584 {
585 struct net_pkt *pkt;
586 struct net_pkt *cloned_pkt;
587
588 NET_INFO("- Cloning packet");
589
590 pkt = net_pkt_rx_alloc_with_buffer(net_iface, 64, AF_UNSPEC, 0, K_NO_WAIT);
591 if (!pkt) {
592 NET_ERR("*** No buffer to allocate");
593 return false;
594 }
595
596 /* Set some arbitrary flags and data */
597 net_pkt_set_ieee802154_ack_fpb(pkt, true);
598 net_pkt_set_ieee802154_lqi(pkt, 50U);
599 net_pkt_set_ieee802154_frame_secured(pkt, true);
600
601 cloned_pkt = net_pkt_clone(pkt, K_NO_WAIT);
602 zassert_not_equal(net_pkt_cb(cloned_pkt), net_pkt_cb(pkt));
603
604 zassert_true(net_pkt_ieee802154_ack_fpb(cloned_pkt));
605 zassert_true(net_pkt_ieee802154_frame_secured(cloned_pkt));
606 zassert_false(net_pkt_ieee802154_mac_hdr_rdy(cloned_pkt));
607 zassert_equal(net_pkt_ieee802154_lqi(cloned_pkt), 50U);
608 zassert_equal(net_pkt_ieee802154_rssi(cloned_pkt), 0U);
609
610 net_pkt_unref(pkt);
611 net_pkt_unref(cloned_pkt);
612
613 return true;
614 }
615
test_packet_rssi_conversion(void)616 static bool test_packet_rssi_conversion(void)
617 {
618 uint8_t raw_signed_rssi_dbm;
619 int8_t signed_rssi_dbm;
620 struct net_pkt *pkt;
621
622 NET_INFO("- RSSI conversion between unsigned and signed representation");
623
624 pkt = net_pkt_rx_alloc_on_iface(net_iface, K_NO_WAIT);
625 if (!pkt) {
626 NET_ERR("*** No pkt to allocate");
627 return false;
628 }
629
630 /* Test setting/getting of unsigned RSSI. */
631 net_pkt_set_ieee802154_rssi(pkt, 50U);
632 zassert_equal(net_pkt_ieee802154_rssi(pkt), 50U);
633
634 /* Test setting/getting of signed RSSI (in range). */
635 net_pkt_set_ieee802154_rssi_dbm(pkt, IEEE802154_MAC_RSSI_DBM_MIN);
636 zassert_equal(net_pkt_ieee802154_rssi(pkt), IEEE802154_MAC_RSSI_MIN);
637 zassert_equal(net_pkt_ieee802154_rssi_dbm(pkt), IEEE802154_MAC_RSSI_DBM_MIN);
638 net_pkt_set_ieee802154_rssi_dbm(pkt, IEEE802154_MAC_RSSI_DBM_MAX);
639 zassert_equal(net_pkt_ieee802154_rssi(pkt), IEEE802154_MAC_RSSI_MAX);
640 zassert_equal(net_pkt_ieee802154_rssi_dbm(pkt), IEEE802154_MAC_RSSI_DBM_MAX);
641 net_pkt_set_ieee802154_rssi_dbm(pkt, 0);
642 zassert_equal(net_pkt_ieee802154_rssi(pkt), 174U);
643 zassert_equal(net_pkt_ieee802154_rssi_dbm(pkt), 0);
644
645 /* Test setting/getting of signed RSSI (outside range). */
646 net_pkt_set_ieee802154_rssi_dbm(pkt, INT16_MIN + 1);
647 zassert_equal(net_pkt_ieee802154_rssi(pkt), IEEE802154_MAC_RSSI_MIN);
648 zassert_equal(net_pkt_ieee802154_rssi_dbm(pkt), IEEE802154_MAC_RSSI_DBM_MIN);
649 net_pkt_set_ieee802154_rssi_dbm(pkt, INT16_MAX);
650 zassert_equal(net_pkt_ieee802154_rssi(pkt), IEEE802154_MAC_RSSI_MAX);
651 zassert_equal(net_pkt_ieee802154_rssi_dbm(pkt), IEEE802154_MAC_RSSI_DBM_MAX);
652
653 /* Test setting/getting of signed RSSI (special value - "no RSSI available"). */
654 net_pkt_set_ieee802154_rssi_dbm(pkt, IEEE802154_MAC_RSSI_DBM_UNDEFINED);
655 zassert_equal(net_pkt_ieee802154_rssi(pkt), IEEE802154_MAC_RSSI_UNDEFINED);
656 zassert_equal(net_pkt_ieee802154_rssi_dbm(pkt), IEEE802154_MAC_RSSI_DBM_UNDEFINED);
657
658 /* Demonstrate setting/getting of signed RSSI represented as a raw
659 * two-complements value in uint8_t (explicit cast required).
660 */
661 raw_signed_rssi_dbm = (uint8_t)-2;
662 net_pkt_set_ieee802154_rssi_dbm(pkt, (int8_t) raw_signed_rssi_dbm);
663 zassert_equal(net_pkt_ieee802154_rssi(pkt), 172U);
664 zassert_equal(net_pkt_ieee802154_rssi_dbm(pkt), -2);
665
666 /* Demonstrate setting/getting of signed RSSI represented as int8_t
667 * (no explicit cast required)
668 */
669 signed_rssi_dbm = -2;
670 net_pkt_set_ieee802154_rssi_dbm(pkt, signed_rssi_dbm);
671 zassert_equal(net_pkt_ieee802154_rssi(pkt), 172U);
672 zassert_equal(net_pkt_ieee802154_rssi_dbm(pkt), -2);
673
674 net_pkt_unref(pkt);
675 return true;
676 }
677
678 #ifdef CONFIG_NET_SOCKETS
test_dgram_packet_sending(void * dst_sll,uint8_t dst_sll_halen,uint32_t security_level)679 static bool test_dgram_packet_sending(void *dst_sll, uint8_t dst_sll_halen, uint32_t security_level)
680 {
681 /* tests should be run sequentially, so no need for context locking */
682 struct ieee802154_context *ctx = net_if_l2_data(net_iface);
683 struct sockaddr_ll socket_sll = {.sll_ifindex = net_if_get_by_iface(net_iface),
684 .sll_family = AF_PACKET,
685 .sll_protocol = ETH_P_IEEE802154};
686 struct sockaddr_ll pkt_dst_sll = {
687 .sll_halen = dst_sll_halen,
688 .sll_protocol = htons(ETH_P_IEEE802154),
689 };
690 uint8_t payload[] = {0x01, 0x02, 0x03, 0x04};
691 struct ieee802154_mpdu mpdu;
692 bool result = false;
693 int fd;
694
695 if (!set_up_security(security_level)) {
696 goto out;
697 }
698
699 NET_INFO("- Sending DGRAM packet via AF_PACKET socket");
700 fd = zsock_socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IEEE802154));
701 if (fd < 0) {
702 NET_ERR("*** Failed to create DGRAM socket : %d", errno);
703 goto reset_security;
704 }
705
706 /* In case we have a short destination address
707 * we simulate an associated device.
708 */
709 /* TODO: support short addresses with encryption (requires neighbour cache) */
710 memcpy(pkt_dst_sll.sll_addr, dst_sll, dst_sll_halen);
711 bool bind_short_address = pkt_dst_sll.sll_halen == IEEE802154_SHORT_ADDR_LENGTH &&
712 security_level == IEEE802154_SECURITY_LEVEL_NONE;
713
714 if (bind_short_address && set_up_short_addr(net_iface, ctx)) {
715 goto release_fd;
716 }
717
718 if (zsock_bind(fd, (const struct sockaddr *)&socket_sll, sizeof(struct sockaddr_ll))) {
719 NET_ERR("*** Failed to bind packet socket : %d", errno);
720 goto release_fd;
721 }
722
723 if (zsock_sendto(fd, payload, sizeof(payload), 0, (const struct sockaddr *)&pkt_dst_sll,
724 sizeof(struct sockaddr_ll)) != sizeof(payload)) {
725 NET_ERR("*** Failed to send, errno %d", errno);
726 goto release_fd;
727 }
728
729 k_yield();
730 k_sem_take(&driver_lock, K_SECONDS(1));
731
732 if (!current_pkt->frags) {
733 NET_ERR("*** Could not send DGRAM packet");
734 goto release_fd;
735 }
736
737 pkt_hexdump(net_pkt_data(current_pkt), net_pkt_get_len(current_pkt));
738
739 if (!ieee802154_validate_frame(net_pkt_data(current_pkt),
740 net_pkt_get_len(current_pkt), &mpdu)) {
741 NET_ERR("*** Sent packet is not valid");
742 goto release_frag;
743 }
744
745 net_pkt_lladdr_src(current_pkt)->addr = net_if_get_link_addr(net_iface)->addr;
746 net_pkt_lladdr_src(current_pkt)->len = net_if_get_link_addr(net_iface)->len;
747
748 if (!ieee802154_decipher_data_frame(net_iface, current_pkt, &mpdu)) {
749 NET_ERR("*** Cannot decipher/authenticate packet");
750 goto release_frag;
751 }
752
753 if (memcmp(mpdu.payload, payload, sizeof(payload)) != 0) {
754 NET_ERR("*** Payload of sent packet is incorrect");
755 goto release_frag;
756 }
757
758 result = true;
759
760 release_frag:
761 net_pkt_frag_unref(current_pkt->frags);
762 current_pkt->frags = NULL;
763 release_fd:
764 tear_down_short_addr(net_iface, ctx);
765 zsock_close(fd);
766 reset_security:
767 tear_down_security();
768 out:
769 return result;
770 }
771
772 /* src_ll_addr is always big endian */
test_dgram_packet_reception(void * src_ll_addr,uint8_t src_ll_addr_len,uint32_t security_level,bool is_broadcast)773 static bool test_dgram_packet_reception(void *src_ll_addr, uint8_t src_ll_addr_len,
774 uint32_t security_level, bool is_broadcast)
775 {
776 struct ieee802154_context *ctx = net_if_l2_data(net_iface);
777 uint8_t our_ext_addr[IEEE802154_EXT_ADDR_LENGTH]; /* big endian */
778 uint8_t payload[] = {0x01, 0x02, 0x03, 0x04};
779 uint16_t our_short_addr = ctx->short_addr; /* CPU byte order */
780 uint8_t ll_hdr_len = 0, authtag_len = 0;
781 struct sockaddr_ll recv_src_sll = {0};
782 uint8_t received_payload[4] = {0};
783 socklen_t recv_src_sll_len;
784 struct net_buf *frame_buf;
785 struct net_pkt *pkt;
786 bool frame_result;
787 int received_len;
788 bool result;
789 int fd;
790
791 result = false;
792
793 sys_memcpy_swap(our_ext_addr, ctx->ext_addr, sizeof(our_ext_addr));
794
795 if (!set_up_security(security_level)) {
796 goto out;
797 }
798
799 NET_INFO("- Receiving DGRAM packet via AF_PACKET socket");
800
801 fd = set_up_recv_socket(SOCK_DGRAM);
802 if (fd < 0) {
803 goto reset_security;
804 }
805
806 pkt = net_pkt_rx_alloc(K_FOREVER);
807 if (!pkt) {
808 NET_ERR("*** Failed to allocate net pkt.");
809 goto release_fd;
810 }
811
812 pkt->lladdr_dst.type = NET_LINK_IEEE802154;
813 pkt->lladdr_dst.addr = is_broadcast ? NULL : our_ext_addr;
814 pkt->lladdr_dst.len = is_broadcast ? 0 : sizeof(ctx->ext_addr);
815
816 if (src_ll_addr_len == IEEE802154_SHORT_ADDR_LENGTH ||
817 src_ll_addr_len == IEEE802154_EXT_ADDR_LENGTH) {
818 pkt->lladdr_src.addr = src_ll_addr;
819 } else {
820 NET_ERR("*** Illegal L2 source address length.");
821 goto release_pkt;
822 }
823 pkt->lladdr_src.len = src_ll_addr_len;
824
825 frame_buf = net_pkt_get_frag(pkt, IEEE802154_MTU, K_FOREVER);
826 if (!frame_buf) {
827 NET_ERR("*** Failed to allocate net pkt frag.");
828 goto release_pkt;
829 }
830
831 ieee802154_compute_header_and_authtag_len(
832 net_iface, net_pkt_lladdr_dst(pkt), net_pkt_lladdr_src(pkt),
833 &ll_hdr_len, &authtag_len);
834
835 net_buf_add(frame_buf, ll_hdr_len);
836 net_buf_add_mem(frame_buf, payload, sizeof(payload));
837 net_buf_add(frame_buf, authtag_len);
838
839 /* Temporarily set the ctx address to the given source address so
840 * we can use ieee802154_create_data_frame().
841 */
842 if (src_ll_addr_len == IEEE802154_SHORT_ADDR_LENGTH) {
843 ctx->short_addr = ntohs(*(uint16_t *)src_ll_addr);
844 } else if (src_ll_addr_len == IEEE802154_EXT_ADDR_LENGTH) {
845 sys_memcpy_swap(ctx->ext_addr, src_ll_addr, sizeof(ctx->ext_addr));
846 } else {
847 NET_ERR("*** Illegal L2 source address length.");
848 goto release_pkt;
849 }
850
851 frame_result = ieee802154_create_data_frame(ctx, net_pkt_lladdr_dst(pkt),
852 net_pkt_lladdr_src(pkt), frame_buf, ll_hdr_len);
853
854 if (src_ll_addr_len == IEEE802154_SHORT_ADDR_LENGTH) {
855 ctx->short_addr = our_short_addr;
856 } else {
857 sys_memcpy_swap(ctx->ext_addr, our_ext_addr, sizeof(ctx->ext_addr));
858 }
859
860 if (!frame_result) {
861 NET_ERR("*** Error while creating data frame.");
862 goto release_pkt;
863 };
864
865 net_pkt_frag_add(pkt, frame_buf);
866
867 if (net_recv_data(net_iface, pkt)) {
868 NET_ERR("*** Error while processing packet.");
869 goto release_pkt;
870 }
871
872 if (current_pkt->frags) {
873 NET_ERR("*** Generated unexpected (ACK?) packet when processing packet.");
874 net_pkt_frag_unref(current_pkt->frags);
875 current_pkt->frags = NULL;
876 goto release_pkt;
877 }
878
879 recv_src_sll_len = sizeof(recv_src_sll);
880 received_len = zsock_recvfrom(fd, received_payload, sizeof(received_payload), 0,
881 (struct sockaddr *)&recv_src_sll, &recv_src_sll_len);
882 if (received_len < 0) {
883 NET_ERR("*** Failed to receive packet, errno %d", errno);
884 goto release_pkt;
885 }
886
887 pkt_hexdump(received_payload, received_len);
888
889 if (received_len != sizeof(payload) || memcmp(received_payload, payload, sizeof(payload))) {
890 NET_ERR("*** Payload of received packet is incorrect");
891 goto release_pkt;
892 }
893
894 if (recv_src_sll_len != sizeof(struct sockaddr_ll) ||
895 recv_src_sll.sll_family != AF_PACKET || recv_src_sll.sll_protocol != ETH_P_IEEE802154 ||
896 recv_src_sll.sll_ifindex != net_if_get_by_iface(net_iface) ||
897 recv_src_sll.sll_halen != src_ll_addr_len ||
898 memcmp(recv_src_sll.sll_addr, src_ll_addr, src_ll_addr_len)) {
899 NET_ERR("*** Source L2 address of received packet is incorrect");
900 goto release_pkt;
901 }
902
903 result = true;
904
905 release_pkt:
906 net_pkt_unref(pkt);
907 release_fd:
908 zsock_close(fd);
909 reset_security:
910 tear_down_security();
911 out:
912 return result;
913 }
914
test_raw_packet_sending(void)915 static bool test_raw_packet_sending(void)
916 {
917 /* tests should be run sequentially, so no need for context locking */
918 struct sockaddr_ll socket_sll = {0};
919 struct ieee802154_mpdu mpdu;
920 struct msghdr msg = {0};
921 struct iovec io_vector;
922 bool result = false;
923 int fd;
924
925 NET_INFO("- Sending RAW packet via AF_PACKET socket");
926
927 fd = zsock_socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IEEE802154));
928 if (fd < 0) {
929 NET_ERR("*** Failed to create RAW socket : %d", errno);
930 goto out;
931 }
932
933 socket_sll.sll_ifindex = net_if_get_by_iface(net_iface);
934 socket_sll.sll_family = AF_PACKET;
935 socket_sll.sll_protocol = ETH_P_IEEE802154;
936
937 if (zsock_bind(fd, (const struct sockaddr *)&socket_sll, sizeof(struct sockaddr_ll))) {
938 NET_ERR("*** Failed to bind packet socket : %d", errno);
939 goto release_fd;
940 }
941
942 io_vector.iov_base = raw_payload;
943 io_vector.iov_len = sizeof(raw_payload);
944 msg.msg_iov = &io_vector;
945 msg.msg_iovlen = 1;
946
947 if (zsock_sendmsg(fd, &msg, 0) != sizeof(raw_payload)) {
948 NET_ERR("*** Failed to send, errno %d", errno);
949 goto release_fd;
950 }
951
952 k_yield();
953 k_sem_take(&driver_lock, K_SECONDS(1));
954
955 if (!current_pkt->frags) {
956 NET_ERR("*** Could not send RAW packet");
957 goto release_fd;
958 }
959
960 pkt_hexdump(net_pkt_data(current_pkt), net_pkt_get_len(current_pkt));
961
962 if (!ieee802154_validate_frame(net_pkt_data(current_pkt),
963 net_pkt_get_len(current_pkt), &mpdu)) {
964 NET_ERR("*** Sent packet is not valid");
965 goto release_frag;
966 }
967
968 if (memcmp(mpdu.payload, &raw_payload[RAW_MAC_PAYLOAD_START_INDEX],
969 RAW_MAC_PAYLOAD_LENGTH) != 0) {
970 NET_ERR("*** Payload of sent packet is incorrect");
971 goto release_frag;
972 }
973
974 result = true;
975
976 release_frag:
977 net_pkt_frag_unref(current_pkt->frags);
978 current_pkt->frags = NULL;
979 release_fd:
980 zsock_close(fd);
981 out:
982 return result;
983 }
984
test_raw_packet_reception(void)985 static bool test_raw_packet_reception(void)
986 {
987 uint8_t received_payload[sizeof(raw_payload)] = {0};
988 struct net_buf *frame_buf;
989 struct net_pkt *pkt;
990 int received_len;
991 bool result;
992 int fd;
993
994 result = false;
995
996 NET_INFO("- Receiving RAW packet via AF_PACKET socket");
997
998 fd = set_up_recv_socket(SOCK_RAW);
999 if (fd < 0) {
1000 goto out;
1001 }
1002
1003 pkt = net_pkt_rx_alloc(K_FOREVER);
1004 if (!pkt) {
1005 NET_ERR("*** Failed to allocate net pkt.");
1006 goto release_fd;
1007 }
1008
1009 frame_buf = net_pkt_get_frag(pkt, sizeof(raw_payload), K_FOREVER);
1010 if (!frame_buf) {
1011 NET_ERR("*** Failed to allocate net pkt frag.");
1012 goto release_pkt;
1013 }
1014
1015 net_buf_add_mem(frame_buf, raw_payload, sizeof(raw_payload));
1016 net_pkt_frag_add(pkt, frame_buf);
1017
1018 if (net_recv_data(net_iface, pkt)) {
1019 NET_ERR("*** Error while processing packet.");
1020 goto release_pkt;
1021 }
1022
1023 if (current_pkt->frags) {
1024 NET_ERR("*** Generated unexpected packet when processing packet.");
1025 net_pkt_frag_unref(current_pkt->frags);
1026 current_pkt->frags = NULL;
1027 goto release_pkt;
1028 }
1029
1030 /* TODO: For POSIX compliance raw packets should be parsed and a LL header be
1031 * extracted. We'll only be able to do so when Zephyr provides hooks to
1032 * call out to L2 from raw socket contexts.
1033 */
1034 received_len = zsock_recv(fd, received_payload, sizeof(received_payload), 0);
1035 if (received_len < 0) {
1036 NET_ERR("*** Failed to receive packet, errno %d", errno);
1037 goto release_pkt;
1038 }
1039
1040 pkt_hexdump(received_payload, received_len);
1041
1042 /* TODO: The received raw packet should actually contain an FCS
1043 * for full compatibility with Linux's raw socket implementation.
1044 * This will only be possible once we
1045 * 1) let HW drivers include FCS if they have it and
1046 * 2) provide a hook for mangling raw packets that allows us
1047 * to include a synthetic FCS if the HW driver does not
1048 * provide one.
1049 */
1050 if (received_len != sizeof(raw_payload) ||
1051 memcmp(received_payload, raw_payload, sizeof(raw_payload))) {
1052 NET_ERR("*** Payload of received packet is incorrect");
1053 goto release_pkt;
1054 }
1055
1056 result = true;
1057
1058 release_pkt:
1059 net_pkt_unref(pkt);
1060 release_fd:
1061 zsock_close(fd);
1062 out:
1063 return result;
1064 }
1065
test_recv_and_send_ack_reply(struct ieee802154_pkt_test * t)1066 static bool test_recv_and_send_ack_reply(struct ieee802154_pkt_test *t)
1067 {
1068 /* Expected uncompressed IPv6 payload. */
1069 static uint8_t expected_rx_pkt[] = {
1070 0x60, 0x00, 0x00, 0x00, /* IPv6, Traffic Class, Flow Label */
1071 0x00, 0x28, /* Payload Length */
1072 0x3a, /* Next header: ICMPv6 */
1073 0xff, /* Hop Limit */
1074 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1075 0x02, 0x12, 0x4b, 0x00, 0x00, 0x9e, 0xa3, 0xc2, /* Source */
1076 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1077 0x00, 0x00, 0x00, 0x01, 0xff, 0x4b, 0x12, 0x00, /* Destination */
1078 0x87, /* Type: NS */
1079 0x00, /* Code*/
1080 0xb7, 0x45, /* Checksum */
1081 0x00, 0x00, 0x00, 0x00, /* Reserved */
1082 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1083 0x70, 0x14, 0xa6, 0x1c, 0x00, 0x4b, 0x12, 0x00, /* Target Address */
1084 0x01, /* ICMPv6 Option: Source LL address */
1085 0x02, /* Length */
1086 0xe5, 0xac, 0xa1, 0x1c, 0x00, 0x4b, 0x12, 0x00, /* LL address */
1087 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Padding */
1088 };
1089 struct ieee802154_context *ctx = net_if_l2_data(net_iface);
1090 struct sockaddr_ll recv_src_sll = {0};
1091 struct sockaddr_ll socket_sll = {
1092 .sll_ifindex = net_if_get_by_iface(net_iface),
1093 .sll_family = AF_PACKET,
1094 .sll_protocol = ETH_P_IEEE802154,
1095 };
1096 uint8_t received_payload[80] = {0};
1097 struct timeval timeo_optval = {
1098 .tv_sec = 1,
1099 .tv_usec = 0,
1100 };
1101 struct ieee802154_mpdu mpdu;
1102 socklen_t recv_src_sll_len;
1103 struct net_pkt *rx_pkt;
1104 bool result = false;
1105 uint8_t mac_be[8];
1106 int received_len;
1107 int fd;
1108
1109 NET_INFO("- Sending ACK reply to a data packet");
1110
1111 fd = zsock_socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IEEE802154));
1112 if (fd < 0) {
1113 NET_ERR("*** Failed to create DGRAM socket : %d", errno);
1114 goto out;
1115 }
1116
1117 if (zsock_bind(fd, (const struct sockaddr *)&socket_sll, sizeof(struct sockaddr_ll))) {
1118 NET_ERR("*** Failed to bind packet socket : %d", errno);
1119 goto release_fd;
1120 }
1121
1122 if (zsock_setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo_optval, sizeof(timeo_optval))) {
1123 NET_ERR("*** Failed to set reception timeout on packet socket : %d", errno);
1124 goto release_fd;
1125 }
1126
1127 if (set_up_short_addr(net_iface, ctx)) {
1128 goto release_fd;
1129 }
1130
1131 rx_pkt = get_data_pkt_with_ar();
1132 if (!rx_pkt) {
1133 goto reset_short_addr;
1134 }
1135
1136 if (net_recv_data(net_iface, rx_pkt) < 0) {
1137 NET_ERR("Recv data failed");
1138 goto release_rx_pkt;
1139 }
1140
1141 recv_src_sll_len = sizeof(recv_src_sll);
1142 received_len = zsock_recvfrom(fd, received_payload, sizeof(received_payload), 0,
1143 (struct sockaddr *)&recv_src_sll, &recv_src_sll_len);
1144 if (received_len < 0) {
1145 NET_ERR("*** Failed to receive packet, errno %d", errno);
1146 goto release_rx_pkt;
1147 }
1148
1149 sys_memcpy_swap(mac_be, ctx->ext_addr, IEEE802154_EXT_ADDR_LENGTH);
1150 if (recv_src_sll_len != sizeof(struct sockaddr_ll) ||
1151 recv_src_sll.sll_ifindex != net_if_get_by_iface(net_iface) ||
1152 recv_src_sll.sll_family != AF_PACKET || recv_src_sll.sll_protocol != ETH_P_IEEE802154 ||
1153 recv_src_sll.sll_halen != IEEE802154_EXT_ADDR_LENGTH ||
1154 memcmp(recv_src_sll.sll_addr, mac_be, IEEE802154_EXT_ADDR_LENGTH)) {
1155 NET_ERR("*** Received socket address does not compare (%d)", -errno);
1156 goto release_rx_pkt;
1157 }
1158
1159 pkt_hexdump(received_payload, received_len);
1160
1161 if (memcmp(expected_rx_pkt, received_payload,
1162 sizeof(expected_rx_pkt))) {
1163 NET_ERR("*** Received uncompressed IPv6 payload does not compare");
1164 goto release_rx_pkt;
1165 }
1166
1167 k_yield();
1168 k_sem_take(&driver_lock, K_SECONDS(1));
1169
1170 /* an ACK packet should be in current_pkt */
1171 if (!current_pkt->frags) {
1172 NET_ERR("*** No ACK reply sent");
1173 goto release_rx_pkt;
1174 }
1175
1176 pkt_hexdump(net_pkt_data(current_pkt), net_pkt_get_len(current_pkt));
1177
1178 if (!ieee802154_validate_frame(net_pkt_data(current_pkt),
1179 net_pkt_get_len(current_pkt), &mpdu)) {
1180 NET_ERR("*** ACK Reply is invalid");
1181 goto release_tx_frag;
1182 }
1183
1184 if (memcmp(mpdu.mhr.fs, t->mhr_check.fc_seq,
1185 sizeof(struct ieee802154_fcf_seq))) {
1186 NET_ERR("*** ACK Reply does not compare");
1187 goto release_tx_frag;
1188 }
1189
1190 if (mpdu.mhr.fs->sequence != t->sequence) {
1191 NET_ERR("*** Sequence number invalid");
1192 goto release_tx_frag;
1193 }
1194
1195 result = true;
1196
1197 release_tx_frag:
1198 net_pkt_frag_unref(current_pkt->frags);
1199 current_pkt->frags = NULL;
1200 release_rx_pkt:
1201 net_pkt_unref(rx_pkt);
1202 reset_short_addr:
1203 tear_down_short_addr(net_iface, ctx);
1204 release_fd:
1205 zsock_close(fd);
1206 out:
1207 return result;
1208 }
1209 #endif /* CONFIG_NET_SOCKETS */
1210
initialize_test_environment(void)1211 static bool initialize_test_environment(void)
1212 {
1213 uint16_t mock_pan_id = MOCK_PAN_ID;
1214 const struct device *dev;
1215
1216 k_sem_reset(&driver_lock);
1217
1218 current_pkt = net_pkt_rx_alloc(K_FOREVER);
1219 if (!current_pkt) {
1220 NET_ERR("*** No buffer to allocate");
1221 return false;
1222 }
1223
1224 dev = device_get_binding("fake_ieee802154");
1225 if (!dev) {
1226 NET_ERR("*** Could not get fake device");
1227 goto release_pkt;
1228 }
1229
1230 net_iface = net_if_lookup_by_dev(dev);
1231 if (!net_iface) {
1232 NET_ERR("*** Could not get fake iface");
1233 goto release_pkt;
1234 }
1235
1236 if (net_mgmt(NET_REQUEST_IEEE802154_SET_PAN_ID, net_iface,
1237 &mock_pan_id, sizeof(mock_pan_id))) {
1238 NET_ERR("*** Failed to set PAN ID in %s.", __func__);
1239 goto release_pkt;
1240 }
1241
1242 NET_INFO("Fake IEEE 802.15.4 network interface ready");
1243
1244 ieee_addr_hexdump(net_if_get_link_addr(net_iface)->addr, 8);
1245
1246 return true;
1247
1248 release_pkt:
1249 net_pkt_unref(current_pkt);
1250 return false;
1251 }
1252
test_setup(void)1253 static void *test_setup(void)
1254 {
1255 bool ret;
1256
1257 ret = initialize_test_environment();
1258
1259 zassert_true(ret, "Test initialization");
1260
1261 return NULL;
1262 }
1263
test_teardown(void * test_fixture)1264 static void test_teardown(void *test_fixture)
1265 {
1266 ARG_UNUSED(test_fixture);
1267
1268 net_pkt_unref(current_pkt);
1269 current_pkt = NULL;
1270 }
1271
ZTEST(ieee802154_l2,test_parsing_ns_pkt)1272 ZTEST(ieee802154_l2, test_parsing_ns_pkt)
1273 {
1274 bool ret;
1275
1276 ret = test_packet_parsing(&test_ns_pkt);
1277
1278 zassert_true(ret, "NS parsed");
1279 }
1280
ZTEST(ieee802154_l2,test_sending_ns_pkt)1281 ZTEST(ieee802154_l2, test_sending_ns_pkt)
1282 {
1283 bool ret;
1284
1285 ret = test_ns_sending(&test_ns_pkt, false);
1286
1287 zassert_true(ret, "NS sent");
1288 }
1289
ZTEST(ieee802154_l2,test_sending_ns_pkt_with_short_addr)1290 ZTEST(ieee802154_l2, test_sending_ns_pkt_with_short_addr)
1291 {
1292 bool ret;
1293
1294 ret = test_ns_sending(&test_ns_pkt, true);
1295
1296 zassert_true(ret, "NS sent");
1297 }
1298
ZTEST(ieee802154_l2,test_parsing_ack_pkt)1299 ZTEST(ieee802154_l2, test_parsing_ack_pkt)
1300 {
1301 bool ret;
1302
1303 ret = test_packet_parsing(&test_ack_pkt);
1304
1305 zassert_true(ret, "ACK parsed");
1306 }
1307
ZTEST(ieee802154_l2,test_waiting_for_ack_pkt)1308 ZTEST(ieee802154_l2, test_waiting_for_ack_pkt)
1309 {
1310 bool ret;
1311
1312 ret = test_wait_for_ack(&test_ack_pkt);
1313
1314 zassert_true(ret, "ACK received");
1315 }
1316
ZTEST(ieee802154_l2,test_parsing_beacon_pkt)1317 ZTEST(ieee802154_l2, test_parsing_beacon_pkt)
1318 {
1319 bool ret;
1320
1321 ret = test_packet_parsing(&test_beacon_pkt);
1322
1323 zassert_true(ret, "Beacon parsed");
1324 }
1325
ZTEST(ieee802154_l2,test_parsing_sec_data_pkt)1326 ZTEST(ieee802154_l2, test_parsing_sec_data_pkt)
1327 {
1328 bool ret;
1329
1330 ret = test_packet_parsing(&test_sec_data_pkt);
1331
1332 zassert_true(ret, "Secured data frame parsed");
1333 }
1334
ZTEST(ieee802154_l2,test_clone_cb)1335 ZTEST(ieee802154_l2, test_clone_cb)
1336 {
1337 bool ret;
1338
1339 ret = test_packet_cloning_with_cb();
1340
1341 zassert_true(ret, "IEEE 802.15.4 net_pkt control block correctly cloned.");
1342 }
1343
ZTEST(ieee802154_l2,test_convert_rssi)1344 ZTEST(ieee802154_l2, test_convert_rssi)
1345 {
1346 bool ret;
1347
1348 ret = test_packet_rssi_conversion();
1349
1350 zassert_true(ret, "IEEE 802.15.4 net_pkt RSSI value correctly converted between dBm and "
1351 "normalized value.");
1352 }
1353
1354 ZTEST_SUITE(ieee802154_l2, NULL, test_setup, NULL, NULL, test_teardown);
1355
1356 #ifdef CONFIG_NET_SOCKETS
ZTEST(ieee802154_l2_sockets,test_receiving_pkt_and_replying_ack_pkt)1357 ZTEST(ieee802154_l2_sockets, test_receiving_pkt_and_replying_ack_pkt)
1358 {
1359 bool ret;
1360
1361 ret = test_recv_and_send_ack_reply(&test_ack_pkt);
1362
1363 zassert_true(ret, "ACK sent");
1364 }
1365
ZTEST(ieee802154_l2_sockets,test_sending_broadcast_dgram_pkt)1366 ZTEST(ieee802154_l2_sockets, test_sending_broadcast_dgram_pkt)
1367 {
1368 uint16_t dst_short_addr = htons(IEEE802154_BROADCAST_ADDRESS);
1369 bool ret;
1370
1371 ret = test_dgram_packet_sending(&dst_short_addr, sizeof(dst_short_addr),
1372 IEEE802154_SECURITY_LEVEL_NONE);
1373
1374 zassert_true(ret, "Broadcast DGRAM packet sent");
1375 }
1376
ZTEST(ieee802154_l2_sockets,test_receiving_broadcast_dgram_pkt)1377 ZTEST(ieee802154_l2_sockets, test_receiving_broadcast_dgram_pkt)
1378 {
1379 uint16_t src_short_addr = htons(0x1234);
1380 bool ret;
1381
1382 ret = test_dgram_packet_reception(&src_short_addr, sizeof(src_short_addr),
1383 IEEE802154_SECURITY_LEVEL_NONE, true);
1384
1385 zassert_true(ret, "Broadcast DGRAM packet received");
1386 }
1387
ZTEST(ieee802154_l2_sockets,test_sending_authenticated_dgram_pkt)1388 ZTEST(ieee802154_l2_sockets, test_sending_authenticated_dgram_pkt)
1389 {
1390 uint16_t dst_short_addr = htons(0x1234);
1391 bool ret;
1392
1393 ret = test_dgram_packet_sending(&dst_short_addr, sizeof(dst_short_addr),
1394 IEEE802154_SECURITY_LEVEL_MIC_128);
1395
1396 zassert_true(ret, "Authenticated DGRAM packet sent");
1397 }
1398
ZTEST(ieee802154_l2_sockets,test_receiving_authenticated_dgram_pkt)1399 ZTEST(ieee802154_l2_sockets, test_receiving_authenticated_dgram_pkt)
1400 {
1401 /* TODO: Receiving authenticated packages with short addresses is not
1402 * yet supported (requires neighbour cache).
1403 */
1404 uint8_t src_ext_addr[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1405 bool ret;
1406
1407 ret = test_dgram_packet_reception(src_ext_addr, sizeof(src_ext_addr),
1408 IEEE802154_SECURITY_LEVEL_MIC_128, false);
1409
1410 zassert_true(ret, "Authenticated DGRAM packet received");
1411 }
1412
ZTEST(ieee802154_l2_sockets,test_sending_encrypted_and_authenticated_dgram_pkt)1413 ZTEST(ieee802154_l2_sockets, test_sending_encrypted_and_authenticated_dgram_pkt)
1414 {
1415 uint8_t dst_ext_addr[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1416 bool ret;
1417
1418 ret = test_dgram_packet_sending(dst_ext_addr, sizeof(dst_ext_addr),
1419 IEEE802154_SECURITY_LEVEL_ENC_MIC_128);
1420
1421 zassert_true(ret, "Encrypted and authenticated DGRAM packet sent");
1422 }
1423
ZTEST(ieee802154_l2_sockets,test_receiving_encrypted_and_authenticated_dgram_pkt)1424 ZTEST(ieee802154_l2_sockets, test_receiving_encrypted_and_authenticated_dgram_pkt)
1425 {
1426 uint8_t src_ext_addr[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1427 bool ret;
1428
1429 ret = test_dgram_packet_reception(src_ext_addr, sizeof(src_ext_addr),
1430 IEEE802154_SECURITY_LEVEL_ENC_MIC_128, false);
1431
1432 zassert_true(ret, "Encrypted and authenticated DGRAM packet received");
1433 }
1434
ZTEST(ieee802154_l2_sockets,test_sending_raw_pkt)1435 ZTEST(ieee802154_l2_sockets, test_sending_raw_pkt)
1436 {
1437 bool ret;
1438
1439 ret = test_raw_packet_sending();
1440
1441 zassert_true(ret, "RAW packet sent");
1442 }
1443
ZTEST(ieee802154_l2_sockets,test_receiving_raw_pkt)1444 ZTEST(ieee802154_l2_sockets, test_receiving_raw_pkt)
1445 {
1446 bool ret;
1447
1448 ret = test_raw_packet_reception();
1449
1450 zassert_true(ret, "RAW packet received");
1451 }
1452
1453 ZTEST_SUITE(ieee802154_l2_sockets, NULL, test_setup, NULL, NULL, test_teardown);
1454 #endif /* CONFIG_NET_SOCKETS */
1455