@@ -444,36 +444,128 @@ static bool test_raw_packet_sending(void)
444444 return result ;
445445}
446446
447- static bool test_ack_reply (struct ieee802154_pkt_test * t )
447+ static bool test_recv_and_ack_reply (struct ieee802154_pkt_test * t )
448448{
449+ /* Incoming IEEE 802.15.4 packet with payload header compression. */
449450 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 ,
459504 };
460505 struct ieee802154_mpdu mpdu ;
461- struct net_pkt * pkt ;
506+ socklen_t recv_src_sll_len ;
462507 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 ;
463513
464514 NET_INFO ("- Sending ACK reply to a data packet\n" );
465515
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 );
468534
469535 memcpy (frag -> data , data_pkt , sizeof (data_pkt ));
470536 frag -> len = sizeof (data_pkt );
471537
472- net_pkt_frag_add (pkt , frag );
538+ net_pkt_frag_add (rx_pkt , frag );
473539
474- if (net_recv_data (iface , pkt ) < 0 ) {
540+ if (net_recv_data (iface , rx_pkt ) < 0 ) {
475541 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 ;
477569 }
478570
479571 k_yield ();
@@ -482,27 +574,34 @@ static bool test_ack_reply(struct ieee802154_pkt_test *t)
482574 /* an ACK packet should be in current_pkt */
483575 if (!current_pkt -> frags ) {
484576 NET_ERR ("*** No ACK reply sent\n" );
485- return false ;
577+ goto release_rx_pkt ;
486578 }
487579
488580 pkt_hexdump (net_pkt_data (current_pkt ), net_pkt_get_len (current_pkt ));
489581
490582 if (!ieee802154_validate_frame (net_pkt_data (current_pkt ),
491583 net_pkt_get_len (current_pkt ), & mpdu )) {
492584 NET_ERR ("*** ACK Reply is invalid\n" );
493- return false ;
585+ goto release_tx_frag ;
494586 }
495587
496588 if (memcmp (mpdu .mhr .fs , t -> mhr_check .fc_seq ,
497589 sizeof (struct ieee802154_fcf_seq ))) {
498590 NET_ERR ("*** ACK Reply does not compare\n" );
499- return false ;
591+ goto release_tx_frag ;
500592 }
501593
594+ result = true;
595+
596+ release_tx_frag :
502597 net_pkt_frag_unref (current_pkt -> frags );
503598 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 ;
506605}
507606
508607static bool test_packet_cloning_with_cb (void )
@@ -609,11 +708,11 @@ ZTEST(ieee802154_l2, test_parsing_ack_pkt)
609708 zassert_true (ret , "ACK parsed" );
610709}
611710
612- ZTEST (ieee802154_l2 , test_replying_ack_pkt )
711+ ZTEST (ieee802154_l2 , test_receiving_pkt_and_replying_ack_pkt )
613712{
614713 bool ret ;
615714
616- ret = test_ack_reply (& test_ack_pkt );
715+ ret = test_recv_and_ack_reply (& test_ack_pkt );
617716
618717 zassert_true (ret , "ACK replied" );
619718}
0 commit comments