@@ -444,36 +444,128 @@ static bool test_raw_packet_sending(void)
444
444
return result ;
445
445
}
446
446
447
- static bool test_ack_reply (struct ieee802154_pkt_test * t )
447
+ static bool test_recv_and_ack_reply (struct ieee802154_pkt_test * t )
448
448
{
449
+ /* Incoming IEEE 802.15.4 packet with payload header compression. */
449
450
static uint8_t data_pkt [] = {
450
- 0x61 , 0xdc , 0x16 , 0xcd , 0xab , 0xc2 , 0xa3 , 0x9e , 0x00 , 0x00 , 0x4b ,
451
- 0x12 , 0x00 , 0x26 , 0x18 , 0x32 , 0x00 , 0x00 , 0x4b , 0x12 , 0x00 , 0x7b ,
452
- 0x00 , 0x3a , 0x20 , 0x01 , 0x0d , 0xb8 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
453
- 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x20 , 0x01 , 0x0d , 0xb8 ,
454
- 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
455
- 0x02 , 0x87 , 0x00 , 0x8b , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x20 , 0x01 ,
456
- 0x0d , 0xb8 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xff ,
457
- 0x16 , 0xf0 , 0x02 , 0xff , 0x16 , 0xf0 , 0x12 , 0xff , 0x16 , 0xf0 , 0x32 ,
458
- 0xff , 0x16 , 0xf0 , 0x00 , 0xff , 0x16 , 0xf0 , 0x00 , 0xff , 0x16
451
+ /* IEEE 802.15.4 MHR */
452
+ 0x61 , 0xd8 , /* FCF with AR bit set */
453
+ 0x16 , /* Sequence */
454
+ 0xcd , 0xab , /* Destination PAN */
455
+ 0xff , 0xff , /* Destination Address */
456
+ 0xc2 , 0xa3 , 0x9e , 0x00 , 0x00 , 0x4b , 0x12 , 0x00 , /* Source Address */
457
+ /* IEEE 802.15.4 MAC Payload */
458
+ 0x7b , 0x39 , /* IPHC header, SAM: compressed, DAM: 48-bits inline */
459
+ 0x3a , /* Next header: ICMPv6 */
460
+ 0x02 , 0x01 , 0xff , 0x4b , 0x12 , 0x00 , /* IPv6 Destination */
461
+ 0x87 , /* Type: NS */
462
+ 0x00 , /* Code*/
463
+ 0xb7 , 0x45 , /* Checksum */
464
+ 0x00 , 0x00 , 0x00 , 0x00 , /* Reserved */
465
+ 0xfe , 0x80 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x70 , 0x14 , 0xa6 , 0x1c , 0x00 , 0x4b ,
466
+ 0x12 , 0x00 , /* Target Address */
467
+ 0x01 , /* ICMPv6 Option: Source LL address */
468
+ 0x02 , /* Length */
469
+ 0xe5 , 0xac , 0xa1 , 0x1c , 0x00 , 0x4b , 0x12 , 0x00 , /* LL address */
470
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , /* Padding */
471
+ };
472
+ /* Expected uncompressed IPv6 payload. */
473
+ static uint8_t expected_rx_pkt [] = {
474
+ 0x60 , 0x00 , 0x00 , 0x00 , /* IPv6, Traffic Class, Flow Label */
475
+ 0x00 , 0x28 , /* Payload Length */
476
+ 0x3a , /* Next header: ICMPv6 */
477
+ 0xff , /* Hop Limit */
478
+ 0xfe , 0x80 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
479
+ 0x02 , 0x12 , 0x4b , 0x00 , 0x00 , 0x9e , 0xa3 , 0xc2 , /* Source */
480
+ 0xff , 0x02 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
481
+ 0x00 , 0x00 , 0x00 , 0x01 , 0xff , 0x4b , 0x12 , 0x00 , /* Destination */
482
+ 0x87 , /* Type: NS */
483
+ 0x00 , /* Code*/
484
+ 0xb7 , 0x45 , /* Checksum */
485
+ 0x00 , 0x00 , 0x00 , 0x00 , /* Reserved */
486
+ 0xfe , 0x80 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
487
+ 0x70 , 0x14 , 0xa6 , 0x1c , 0x00 , 0x4b , 0x12 , 0x00 , /* Target Address */
488
+ 0x01 , /* ICMPv6 Option: Source LL address */
489
+ 0x02 , /* Length */
490
+ 0xe5 , 0xac , 0xa1 , 0x1c , 0x00 , 0x4b , 0x12 , 0x00 , /* LL address */
491
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , /* Padding */
492
+ };
493
+ struct ieee802154_context * ctx = net_if_l2_data (iface );
494
+ struct sockaddr_ll recv_src_sll = {0 };
495
+ struct sockaddr_ll socket_sll = {
496
+ .sll_ifindex = net_if_get_by_iface (iface ),
497
+ .sll_family = AF_PACKET ,
498
+ .sll_protocol = ETH_P_IEEE802154 ,
499
+ };
500
+ uint8_t received_payload [80 ] = {0 };
501
+ struct timeval timeo_optval = {
502
+ .tv_sec = 1 ,
503
+ .tv_usec = 0 ,
459
504
};
460
505
struct ieee802154_mpdu mpdu ;
461
- struct net_pkt * pkt ;
506
+ socklen_t recv_src_sll_len ;
462
507
struct net_buf * frag ;
508
+ struct net_pkt * rx_pkt ;
509
+ bool result = false;
510
+ uint8_t mac_be [8 ];
511
+ int received_len ;
512
+ int fd ;
463
513
464
514
NET_INFO ("- Sending ACK reply to a data packet\n" );
465
515
466
- pkt = net_pkt_rx_alloc (K_FOREVER );
467
- frag = net_pkt_get_frag (pkt , sizeof (data_pkt ), K_FOREVER );
516
+ fd = socket (AF_PACKET , SOCK_DGRAM , ETH_P_IEEE802154 );
517
+ if (fd < 0 ) {
518
+ NET_ERR ("*** Failed to create DGRAM socket : %d\n" , errno );
519
+ goto out ;
520
+ }
521
+
522
+ if (bind (fd , (const struct sockaddr * )& socket_sll , sizeof (struct sockaddr_ll ))) {
523
+ NET_ERR ("*** Failed to bind packet socket : %d\n" , errno );
524
+ goto release_fd ;
525
+ }
526
+
527
+ if (setsockopt (fd , SOL_SOCKET , SO_RCVTIMEO , & timeo_optval , sizeof (timeo_optval ))) {
528
+ NET_ERR ("*** Failed to set reception timeout on packet socket : %d\n" , errno );
529
+ goto release_fd ;
530
+ }
531
+
532
+ rx_pkt = net_pkt_rx_alloc (K_FOREVER );
533
+ frag = net_pkt_get_frag (rx_pkt , sizeof (data_pkt ), K_FOREVER );
468
534
469
535
memcpy (frag -> data , data_pkt , sizeof (data_pkt ));
470
536
frag -> len = sizeof (data_pkt );
471
537
472
- net_pkt_frag_add (pkt , frag );
538
+ net_pkt_frag_add (rx_pkt , frag );
473
539
474
- if (net_recv_data (iface , pkt ) < 0 ) {
540
+ if (net_recv_data (iface , rx_pkt ) < 0 ) {
475
541
NET_ERR ("Recv data failed" );
476
- return false;
542
+ goto release_rx_pkt ;
543
+ }
544
+
545
+ recv_src_sll_len = sizeof (recv_src_sll );
546
+ received_len = recvfrom (fd , received_payload , sizeof (received_payload ), 0 ,
547
+ (struct sockaddr * )& recv_src_sll , & recv_src_sll_len );
548
+ if (received_len < 0 ) {
549
+ NET_ERR ("*** Failed to receive packet, errno %d\n" , errno );
550
+ goto release_rx_pkt ;
551
+ }
552
+
553
+ sys_memcpy_swap (mac_be , ctx -> ext_addr , IEEE802154_EXT_ADDR_LENGTH );
554
+ if (recv_src_sll_len != sizeof (struct sockaddr_ll ) ||
555
+ recv_src_sll .sll_ifindex != net_if_get_by_iface (iface ) ||
556
+ recv_src_sll .sll_family != AF_PACKET || recv_src_sll .sll_protocol != ETH_P_IEEE802154 ||
557
+ recv_src_sll .sll_halen != IEEE802154_EXT_ADDR_LENGTH ||
558
+ memcmp (recv_src_sll .sll_addr , mac_be , IEEE802154_EXT_ADDR_LENGTH )) {
559
+ NET_ERR ("*** Received socket address does not compare\n" , errno );
560
+ goto release_rx_pkt ;
561
+ }
562
+
563
+ pkt_hexdump (received_payload , received_len );
564
+
565
+ if (memcmp (expected_rx_pkt , received_payload ,
566
+ sizeof (expected_rx_pkt ))) {
567
+ NET_ERR ("*** Received uncompressed IPv6 payload does not compare\n" );
568
+ goto release_rx_pkt ;
477
569
}
478
570
479
571
k_yield ();
@@ -482,27 +574,34 @@ static bool test_ack_reply(struct ieee802154_pkt_test *t)
482
574
/* an ACK packet should be in current_pkt */
483
575
if (!current_pkt -> frags ) {
484
576
NET_ERR ("*** No ACK reply sent\n" );
485
- return false ;
577
+ goto release_rx_pkt ;
486
578
}
487
579
488
580
pkt_hexdump (net_pkt_data (current_pkt ), net_pkt_get_len (current_pkt ));
489
581
490
582
if (!ieee802154_validate_frame (net_pkt_data (current_pkt ),
491
583
net_pkt_get_len (current_pkt ), & mpdu )) {
492
584
NET_ERR ("*** ACK Reply is invalid\n" );
493
- return false ;
585
+ goto release_tx_frag ;
494
586
}
495
587
496
588
if (memcmp (mpdu .mhr .fs , t -> mhr_check .fc_seq ,
497
589
sizeof (struct ieee802154_fcf_seq ))) {
498
590
NET_ERR ("*** ACK Reply does not compare\n" );
499
- return false ;
591
+ goto release_tx_frag ;
500
592
}
501
593
594
+ result = true;
595
+
596
+ release_tx_frag :
502
597
net_pkt_frag_unref (current_pkt -> frags );
503
598
current_pkt -> frags = NULL ;
504
-
505
- return true;
599
+ release_rx_pkt :
600
+ net_pkt_unref (rx_pkt );
601
+ release_fd :
602
+ close (fd );
603
+ out :
604
+ return result ;
506
605
}
507
606
508
607
static bool test_packet_cloning_with_cb (void )
@@ -609,11 +708,11 @@ ZTEST(ieee802154_l2, test_parsing_ack_pkt)
609
708
zassert_true (ret , "ACK parsed" );
610
709
}
611
710
612
- ZTEST (ieee802154_l2 , test_replying_ack_pkt )
711
+ ZTEST (ieee802154_l2 , test_receiving_pkt_and_replying_ack_pkt )
613
712
{
614
713
bool ret ;
615
714
616
- ret = test_ack_reply (& test_ack_pkt );
715
+ ret = test_recv_and_ack_reply (& test_ack_pkt );
617
716
618
717
zassert_true (ret , "ACK replied" );
619
718
}
0 commit comments