@@ -155,6 +155,8 @@ struct kw41z_context {
155155
156156 u32_t rx_warmup_time ;
157157 u32_t tx_warmup_time ;
158+
159+ bool frame_pending ; /* FP bit state from the most recent ACK frame. */
158160};
159161
160162static struct kw41z_context kw41z_context_data ;
@@ -569,6 +571,47 @@ static inline void kw41z_rx(struct kw41z_context *kw41z, u8_t len)
569571 }
570572}
571573
574+ #define ACK_FRAME_LEN 3
575+ #define ACK_FRAME_TYPE (2 << 0)
576+ #define ACK_FRAME_PENDING_BIT (1 << 4)
577+
578+ static void handle_ack (struct kw41z_context * kw41z , u8_t seq_number )
579+ {
580+ struct net_pkt * ack_pkt ;
581+ u8_t ack_psdu [ACK_FRAME_LEN ];
582+
583+ ack_pkt = net_pkt_alloc_with_buffer (kw41z -> iface , ACK_FRAME_LEN ,
584+ AF_UNSPEC , 0 , K_NO_WAIT );
585+ if (!ack_pkt ) {
586+ LOG_ERR ("No free packet available." );
587+ return ;
588+ }
589+
590+ /* Re-create ACK frame. */
591+ ack_psdu [0 ] = kw41z_context_data .frame_pending ?
592+ ACK_FRAME_TYPE | ACK_FRAME_PENDING_BIT : ACK_FRAME_TYPE ;
593+ ack_psdu [1 ] = 0 ;
594+ ack_psdu [2 ] = seq_number ;
595+
596+ if (net_pkt_write (ack_pkt , ack_psdu , sizeof (ack_psdu )) < 0 ) {
597+ LOG_ERR ("Failed to write to a packet." );
598+ goto out ;
599+ }
600+
601+ /* Use some fake values for LQI and RSSI. */
602+ (void )net_pkt_set_ieee802154_lqi (ack_pkt , 80 );
603+ (void )net_pkt_set_ieee802154_rssi (ack_pkt , -40 );
604+
605+ net_pkt_cursor_init (ack_pkt );
606+
607+ if (ieee802154_radio_handle_ack (kw41z -> iface , ack_pkt ) != NET_OK ) {
608+ LOG_INF ("ACK packet not handled - releasing." );
609+ }
610+
611+ out :
612+ net_pkt_unref (ack_pkt );
613+ }
614+
572615static int kw41z_tx (struct device * dev , struct net_pkt * pkt ,
573616 struct net_buf * frag )
574617{
@@ -653,6 +696,10 @@ static int kw41z_tx(struct device *dev, struct net_pkt *pkt,
653696 irq_unlock (key );
654697 k_sem_take (& kw41z -> seq_sync , K_FOREVER );
655698
699+ if ((kw41z -> seq_retval == 0 ) && ieee802154_is_ar_flag_set (frag )) {
700+ handle_ack (kw41z , frag -> data [2 ]);
701+ }
702+
656703 LOG_DBG ("seq_retval: %d" , kw41z -> seq_retval );
657704 return kw41z -> seq_retval ;
658705}
@@ -795,6 +842,9 @@ static void kw41z_isr(int unused)
795842 case KW41Z_STATE_TXRX :
796843 LOG_DBG ("TXRX seq done" );
797844 kw41z_tmr3_disable ();
845+ /* Store the frame pending bit status. */
846+ kw41z_context_data .frame_pending =
847+ irqsts & ZLL_IRQSTS_RX_FRM_PEND_MASK ;
798848 case KW41Z_STATE_TX :
799849 LOG_DBG ("TX seq done" );
800850 KW_DBG_TRACE (KW41_DBG_TRACE_TX , irqsts ,
0 commit comments