@@ -231,9 +231,7 @@ static uint32_t crc_partial_finalize(const size_t n_bytes, const uint32_t crc_ac
231231
232232#define HEADER_SIZE_BYTES 48U
233233#define HEADER_VERSION 2U
234-
235- #define HEADER_FLAG_EOT 0x01U
236- #define HEADER_FLAG_ACK 0x02U
234+ #define HEADER_FLAG_ACK 0x01U
237235
238236typedef struct
239237{
@@ -285,16 +283,12 @@ static const byte_t* deserialize_u64(const byte_t* ptr, uint64_t* const out_valu
285283
286284static byte_t * header_serialize (byte_t * const buffer ,
287285 const meta_t meta ,
288- const bool flag_eot ,
289286 const uint32_t frame_index ,
290287 const uint32_t frame_payload_offset ,
291288 const uint32_t prefix_crc )
292289{
293290 byte_t * ptr = buffer ;
294291 byte_t flags = 0 ;
295- if (flag_eot ) {
296- flags |= HEADER_FLAG_EOT ;
297- }
298292 if (meta .flag_ack ) {
299293 flags |= HEADER_FLAG_ACK ;
300294 }
@@ -316,7 +310,6 @@ static byte_t* header_serialize(byte_t* const buffer,
316310
317311static bool header_deserialize (const udpard_bytes_mut_t dgram_payload ,
318312 meta_t * const out_meta ,
319- bool * const flag_eot ,
320313 uint32_t * const frame_index ,
321314 uint32_t * const frame_payload_offset ,
322315 uint32_t * const prefix_crc ,
@@ -332,7 +325,6 @@ static bool header_deserialize(const udpard_bytes_mut_t dgram_payload,
332325 if (version == HEADER_VERSION ) {
333326 out_meta -> priority = (udpard_prio_t )((byte_t )(head >> 5U ) & 0x07U );
334327 const byte_t flags = * ptr ++ ;
335- * flag_eot = (flags & HEADER_FLAG_EOT ) != 0U ;
336328 out_meta -> flag_ack = (flags & HEADER_FLAG_ACK ) != 0U ;
337329 ptr += 2U ;
338330 ptr = deserialize_u32 (ptr , frame_index );
@@ -343,6 +335,7 @@ static bool header_deserialize(const udpard_bytes_mut_t dgram_payload,
343335 ptr = deserialize_u64 (ptr , & out_meta -> topic_hash );
344336 ptr = deserialize_u32 (ptr , prefix_crc );
345337 (void )ptr ;
338+ // TODO: validate the fields (e.g., ensure offset+size does not exceed the transfer payload size)
346339 // Set up the output payload view.
347340 out_payload -> size = dgram_payload .size - HEADER_SIZE_BYTES ;
348341 out_payload -> data = (byte_t * )dgram_payload .data + HEADER_SIZE_BYTES ;
@@ -490,19 +483,13 @@ static tx_chain_t tx_spool(const udpard_tx_mem_resources_t memory,
490483 if (NULL == out .tail ) {
491484 break ;
492485 }
493- const bool last = (payload .size - offset ) <= mtu ;
494486 const byte_t * const read_ptr = ((const byte_t * )payload .data ) + offset ;
495487 prefix_crc = crc_add (prefix_crc , progress , read_ptr );
496- byte_t * const write_ptr = header_serialize (item -> datagram_payload .data , //
497- meta ,
498- last ,
499- (uint32_t )out .count ,
500- (uint32_t )offset ,
501- prefix_crc ^ CRC_OUTPUT_XOR );
488+ byte_t * const write_ptr = header_serialize (
489+ item -> datagram_payload .data , meta , (uint32_t )out .count , (uint32_t )offset , prefix_crc ^ CRC_OUTPUT_XOR );
502490 (void )memcpy (write_ptr , read_ptr , progress ); // NOLINT(*DeprecatedOrUnsafeBufferHandling)
503491 offset += progress ;
504492 UDPARD_ASSERT (offset <= payload .size );
505- UDPARD_ASSERT ((!last ) || (offset == payload .size ));
506493 out .count ++ ;
507494 } while (offset < payload .size );
508495 UDPARD_ASSERT ((offset == payload .size ) || (out .tail == NULL ));
@@ -721,31 +708,23 @@ typedef struct rx_fragment_t
721708 udpard_tree_t tree ;
722709} rx_fragment_t ;
723710
724- typedef struct
725- {
726- uint32_t max_index ; ///< Maximum observed frame index in this transfer (so far); zero upon restart.
727- uint32_t eot_index ; ///< Discovered EOT frame index.
728- bool eot_discovered ;
729- uint32_t accepted_frames ; ///< Number of frames accepted so far.
730- size_t payload_size_stored ; ///< Grows with each accepted fragment (out of order).
731- uint32_t crc ; ///< CRC reconstruction state.
732- udpard_tree_t * fragments ;
733- } rx_slot_iface_t ;
734-
735711typedef enum
736712{
737713 rx_slot_idle = 0 ,
738714 rx_slot_busy = 1 ,
739715 rx_slot_done = 2 ,
740716} rx_slot_state_t ;
741717
718+ /// Frames from all redundant interfaces are pooled into the same reassembly slot per transfer-ID.
719+ /// The redundant interfaces may use distinct MTU, which requires special handling.
742720typedef struct
743721{
744722 rx_slot_state_t state ;
745- udpard_microsecond_t ts_discovery ; ///< The timestamp of the first frame received for this transfer.
746- udpard_microsecond_t ts_completion ; ///< The timestamp of the final accepted frame for this transfer.
747- uint64_t transfer_id ;
748- rx_slot_iface_t iface [UDPARD_NETWORK_INTERFACE_COUNT_MAX ];
723+ uint64_t transfer_id ; ///< Which transfer we're reassembling here.
724+ udpard_microsecond_t ts_discovery ; ///< The timestamp of the first frame received for this transfer.
725+ udpard_microsecond_t ts_completion ; ///< The timestamp of the final accepted frame for this transfer.
726+ size_t covered_prefix ; ///< Number of bytes received contiguously from offset zero.
727+ udpard_tree_t * fragments ;
749728} rx_slot_t ;
750729
751730/// Starts with zeros. Remembers the bit values per transfer-ID within the window.
@@ -824,6 +803,7 @@ typedef struct
824803 udpard_list_member_t list_by_animation ;
825804 udpard_microsecond_t last_animated_ts ;
826805
806+ /// To weed out duplicates and to retransmit lost ACKs.
827807 rx_transfer_id_window_t transfer_id_received ;
828808
829809 rx_slot_t slots [RX_SLOT_COUNT ];
0 commit comments