@@ -481,14 +481,28 @@ static bool addr_add(const uint8_t * p_addr,
481481 return false;
482482 }
483483
484- memmove (p_addr_array + entry_size * (location + 1 ),
485- p_addr_array + entry_size * (location ),
484+ uint8_t * p_entry_at_location = p_addr_array + entry_size * location ;
485+
486+ memmove (p_entry_at_location + entry_size ,
487+ p_entry_at_location ,
486488 (* p_addr_array_len - location ) * entry_size );
487489
488- memcpy (p_addr_array + entry_size * location ,
490+ memcpy (p_entry_at_location ,
489491 p_addr ,
490492 extended ? EXTENDED_ADDRESS_SIZE : SHORT_ADDRESS_SIZE );
491493
494+ if (data_type == NRF_802154_ACK_DATA_IE )
495+ {
496+ /* The content of ie_data_t in the structure indexed by location
497+ * is uninitialized (can have old content). Let's initialize it. */
498+ ie_data_t * p_ie_data = extended ?
499+ & (((ack_ext_ie_data_t * )p_entry_at_location )-> ie_data ) :
500+ & (((ack_short_ie_data_t * )p_entry_at_location )-> ie_data );
501+
502+ p_ie_data -> len = 0U ;
503+ /* p_ie_data->p_data does not need initialization when len is set to zero. */
504+ }
505+
492506 (* p_addr_array_len )++ ;
493507
494508 return true;
@@ -562,18 +576,60 @@ static bool addr_remove(uint32_t location, nrf_802154_ack_data_t data_type, bool
562576 return true;
563577}
564578
565- static void ie_data_add (uint32_t location , bool extended , const uint8_t * p_data , uint8_t data_len )
579+ /**
580+ * @brief Replace or append an Information Element to the ACK data.
581+ *
582+ * If the target ACK data already contains an Information Element with the same
583+ * ID as the new Information Element, the existing IE is replaced with the new
584+ * one. Otherwise, the new IE is appended to the target ACK data.
585+ *
586+ * @param[in] location Index of the ACK data buffer to be modified.
587+ * @param[in] extended Indication whether the ACK data buffer for
588+ * an extended or a short address is to be modified.
589+ * @param[in] p_data New Information Element data.
590+ * @param[in] data_len New Information Element data length.
591+ *
592+ * @retval true The new Information Element has been added successfully.
593+ * @retval false The new Information Element has not fitted in the buffer.
594+ */
595+ static bool ie_data_set (uint32_t location , bool extended , const uint8_t * p_data , uint8_t data_len )
566596{
567- if (extended )
597+ ie_data_t * ie_data =
598+ extended ? & m_ie .ext_data [location ].ie_data : & m_ie .short_data [location ].ie_data ;
599+
600+ const uint8_t new_ie_id = nrf_802154_frame_parser_ie_id_get (p_data );
601+
602+ for (const uint8_t * ie = nrf_802154_frame_parser_header_ie_iterator_begin (ie_data -> p_data );
603+ nrf_802154_frame_parser_ie_iterator_end (ie , ie_data -> p_data + ie_data -> len ) == false;
604+ ie = nrf_802154_frame_parser_ie_iterator_next (ie ))
568605 {
569- memcpy (m_ie .ext_data [location ].ie_data .p_data , p_data , data_len );
570- m_ie .ext_data [location ].ie_data .len = data_len ;
606+ if (nrf_802154_frame_parser_ie_id_get (ie ) != new_ie_id )
607+ {
608+ continue ;
609+ }
610+
611+ if (IE_DATA_OFFSET + nrf_802154_frame_parser_ie_length_get (ie ) != data_len )
612+ {
613+ /* Overwriting an existing IE with a different size is not supported. */
614+ return false;
615+ }
616+
617+ memcpy ((uint8_t * )ie , p_data , data_len );
618+ return true;
571619 }
572- else
620+
621+ /* Append IE data with the new IE. */
622+
623+ if (ie_data -> len + data_len > NRF_802154_MAX_ACK_IE_SIZE )
573624 {
574- memcpy ( m_ie . short_data [ location ]. ie_data . p_data , p_data , data_len );
575- m_ie . short_data [ location ]. ie_data . len = data_len ;
625+ /* No space to fit it the new IE. */
626+ return false ;
576627 }
628+
629+ memcpy (ie_data -> p_data + ie_data -> len , p_data , data_len );
630+ ie_data -> len += data_len ;
631+
632+ return true;
577633}
578634
579635/***************************************************************************************************
@@ -607,7 +663,7 @@ bool nrf_802154_ack_data_for_addr_set(const uint8_t * p_addr,
607663 {
608664 if (data_type == NRF_802154_ACK_DATA_IE )
609665 {
610- ie_data_add (location , extended , p_data , data_len );
666+ return ie_data_set (location , extended , p_data , data_len );
611667 }
612668
613669 return true;
0 commit comments