@@ -125,7 +125,7 @@ typedef struct udpard_udpip_ep_t
125125/// The remote information can be used for sending P2P responses back to the sender, if needed.
126126/// The RX pipeline will attempt to discover the sender's UDP/IP endpoint per redundant interface
127127/// based on the source address of the received UDP datagrams. If the sender's endpoint could not be discovered
128- /// for a certain interface, the corresponding entry in the origin array will be zeroed.
128+ /// for a certain interface, the corresponding entry in the endpoints array will be zeroed.
129129/// Note that this allows the sender to change its network interface address dynamically.
130130/// The library does not make any assumptions about the specific values and their uniqueness;
131131/// as such, multiple remote nodes can even share the same endpoint.
@@ -254,14 +254,15 @@ size_t udpard_fragment_gather(const udpard_fragment_t* any_frag,
254254/// |
255255/// +---> ...
256256///
257- /// The library supports configurable DSCP marking of the outgoing UDP datagrams as a function of Cyphal transfer
258- /// priority level. This is configured separately per TX pipeline instance (i.e., per network interface).
257+ /// Applications can mark outgoing datagrams with DSCP values derived from the Cyphal transfer priority when sending
258+ /// items pulled from a TX queue. The library itself does not touch the DSCP field but exposes the transfer priority
259+ /// on every enqueued item so the application can apply its own mapping as needed.
259260/// The maximum transmission unit (MTU) can also be configured separately per TX pipeline instance.
260261/// Applications that are interested in maximizing their wire compatibility should not change the default MTU setting.
261262
262263/// A TX queue uses these memory resources for allocating the enqueued items (UDP datagrams).
263264/// There are exactly two allocations per enqueued item:
264- /// - the first for bookkeeping purposes (UdpardTxItem )
265+ /// - the first for bookkeeping purposes (udpard_tx_item_t )
265266/// - second for payload storage (the frame data)
266267/// In a simple application, there would be just one memory resource shared by all parts of the library.
267268/// If the application knows its MTU, it can use block allocation to avoid extrinsic fragmentation.
@@ -304,13 +305,13 @@ typedef struct udpard_tx_t
304305
305306 /// The maximum number of Cyphal transfer payload bytes per UDP datagram.
306307 /// The Cyphal/UDP header is added to this value to obtain the total UDP datagram payload size. See UDPARD_MTU_*.
307- /// The value can be changed arbitrarily at any time between enqueue operations.
308+ /// The value can be changed arbitrarily at any time between enqueue operations; values below UDPARD_MTU_MIN
309+ /// are ignored during enqueue and the minimum is used instead.
308310 size_t mtu ;
309311
310- /// The mapping from the Cyphal priority level in [0,7], where the highest priority is at index 0
311- /// and the lowest priority is at the last element of the array, to the IP DSCP field value.
312- /// By default, the mapping is initialized per the recommendations given in the Cyphal/UDP specification.
313- /// The value can be changed arbitrarily at any time between enqueue operations.
312+ /// Optional user-managed mapping from the Cyphal priority level in [0,7] (highest priority at index 0)
313+ /// to the IP DSCP field value for use by the application when transmitting. The library does not populate
314+ /// or otherwise use this array; udpard_tx_new() leaves it zero-initialized.
314315 uint_least8_t dscp_value_per_priority [UDPARD_PRIORITY_MAX + 1U ];
315316
316317 udpard_tx_mem_resources_t memory ;
@@ -330,7 +331,8 @@ typedef struct udpard_tx_t
330331} udpard_tx_t ;
331332
332333/// One UDP datagram stored in the udpard_tx_t transmission queue along with its metadata.
333- /// The datagram should be sent to the indicated UDP/IP endpoint with the specified DSCP value.
334+ /// The datagram should be sent to the indicated UDP/IP endpoint with the DSCP value chosen by the application,
335+ /// e.g., via its own mapping from udpard_prio_t.
334336/// The datagram should be discarded (transmission aborted) if the deadline has expired.
335337/// All fields are READ-ONLY except the mutable `datagram_payload` field, which could be nullified to indicate
336338/// a transfer of the payload memory ownership to somewhere else.
@@ -346,7 +348,7 @@ typedef struct udpard_tx_item_t
346348 /// remote nodes anyway, so all its remaining frames can be dropped from the queue at once using udpard_tx_pop().
347349 struct udpard_tx_item_t * next_in_transfer ;
348350
349- /// This is the same value that is passed to udpard_tx_publish()/p2p ().
351+ /// This is the same value that is passed to udpard_tx_push ().
350352 /// Frames whose transmission deadline is in the past are dropped (transmission aborted).
351353 udpard_us_t deadline ;
352354
@@ -366,12 +368,13 @@ typedef struct udpard_tx_item_t
366368 void * user_transfer_reference ;
367369} udpard_tx_item_t ;
368370
369- /// The parameters will be initialized to the recommended defaults automatically,
370- /// which can be changed later by modifying the struct fields directly.
371- /// No memory allocation is going to take place until the pipeline is actually written to.
371+ /// The parameters are initialized deterministically (MTU defaults to UDPARD_MTU_DEFAULT and counters are reset)
372+ /// and can be changed later by modifying the struct fields directly. No memory allocation is going to take place
373+ /// until the pipeline is actually written to.
372374///
373375/// The instance does not hold any resources itself except for the allocated memory.
374- /// To safely discard it, simply pop all enqueued frames from it.
376+ /// To safely discard it, simply pop all enqueued frames from it using udpard_tx_pop() and free their memory
377+ /// using udpard_tx_free(), then discard the instance itself.
375378///
376379/// True on success, false if any of the arguments are invalid.
377380bool udpard_tx_new (udpard_tx_t * const self ,
@@ -399,22 +402,21 @@ bool udpard_tx_new(udpard_tx_t* const self,
399402/// such that it is likely to be distinct per application startup (embedded systems can use noinit memory sections,
400403/// hash uninitialized SRAM, use timers or ADC noise, etc).
401404///
402- /// The user_transfer_reference is an opaque pointer that will be assigned to the user_transfer_reference field of
403- /// each enqueued item. The library itself does not use or check this value in any way, so it can be NULL if not needed.
405+ /// The user_transfer_reference is an opaque pointer that will be assigned to the eponymous field of each enqueued item.
406+ /// The library itself does not use or check this value in any way, so it can be NULL if not needed.
404407///
405408/// The deadline value will be used to populate the eponymous field of the generated datagrams (all will share the
406- /// same deadline value). This feature is intended to allow aborting frames that could not be transmitted before
407- /// the specified deadline; therefore, the timestamp value should be in the future.
409+ /// same deadline value). This is used for aborting frames that could not be transmitted before the specified deadline.
408410///
409411/// The function returns the number of UDP datagrams enqueued, which is always a positive number, in case of success.
410- /// In case of failure, the function returns zero, with the corresponding error counters incremented.
411- /// In case of an error, no frames are added to the queue; in other words, either all frames of the transfer are
412- /// enqueued successfully, or none are.
412+ /// In case of failure, the function returns zero. Runtime failures increment the corresponding error counters,
413+ /// while invocations with invalid arguments just return zero without modifying the queue state. In all cases,
414+ /// either all frames of the transfer are enqueued successfully or none are.
413415///
414416/// The memory allocation requirement is two allocations per datagram:
415417/// a single-frame transfer takes two allocations; a multi-frame transfer of N frames takes N*2 allocations.
416418/// In each pair of allocations:
417- /// - the first allocation is for `udpard_tx_t `; the size is `sizeof(udpard_tx_t )`;
419+ /// - the first allocation is for `udpard_tx_item_t `; the size is `sizeof(udpard_tx_item_t )`;
418420/// the TX queue `memory.fragment` memory resource is used for this allocation (and later for deallocation);
419421/// - the second allocation is for payload storage (the datagram data) - size is normally MTU but could be less for
420422/// the last frame of the transfer; the TX queue `memory.payload` resource is used for this allocation.
@@ -455,10 +457,11 @@ void udpard_tx_free(const udpard_tx_mem_resources_t memory, udpard_tx_item_t* co
455457
456458/// The reception (RX) pipeline is used to subscribe to subjects and to receive P2P transfers.
457459/// The reception pipeline is highly robust and is able to accept datagrams with arbitrary MTU,
458- /// frames delivered out-of-order (OOO) with arbitrary duplication, and/or frames interleaved between transfers.
459- /// The support for OOO reassembly is particularly interesting when simple repetition coding FEC is used.
460- /// All redundant interfaces are pooled together into a single RX stream per RX port,
460+ /// frames delivered out-of-order (OOO) with duplication and interleaving between transfers.
461+ /// Robust OOO reassembly is particularly interesting when simple repetition coding FEC is used.
462+ /// All redundant interfaces are pooled together into a single fragment stream per RX port,
461463/// thus providing seamless failover and great resilience against packet loss on any of the interfaces.
464+ /// The RX pipeline operates at the speed/latency of the best-performing interface at any given time.
462465///
463466/// The application should instantiate one RX port instance per subject it needs to receive messages from,
464467/// irrespective of the number of redundant interfaces. There needs to be one socket (or a similar abstraction
@@ -488,7 +491,7 @@ void udpard_tx_free(const udpard_tx_mem_resources_t memory, udpard_tx_item_t* co
488491/// STATELESS Constant time, constant memory 1-frame only, dups, no responses UDPARD_REORDERING_WINDOW_STATELESS
489492///
490493/// If not sure, choose the ORDERED mode with a ~5 ms reordering window for all topics except for request-response
491- /// RPC-style, in which case choose UNORDERED. The STATELESS mode is chiefly intended just for the heartbeat topic.
494+ /// RPC-style, in which case choose UNORDERED. The STATELESS mode is chiefly intended for the heartbeat topic.
492495///
493496/// ORDERED
494497///
@@ -529,7 +532,7 @@ void udpard_tx_free(const udpard_tx_mem_resources_t memory, udpard_tx_item_t* co
529532/// variable-complexity processing logic, enabling great scalability for topics with a very large number of
530533/// publishers where unordered and duplicated messages are acceptable, such as the heartbeat topic.
531534///
532- /// The UNORDERED mode is used if the reordering window duration is set to UDPARD_REORDERING_WINDOW_STATELESS.
535+ /// The STATELESS mode is used if the reordering window duration is set to UDPARD_REORDERING_WINDOW_STATELESS.
533536
534537#define UDPARD_RX_REORDERING_WINDOW_UNORDERED ((udpard_us_t)(-1))
535538#define UDPARD_RX_REORDERING_WINDOW_STATELESS ((udpard_us_t)(-2))
@@ -568,8 +571,7 @@ typedef struct udpard_rx_port_t
568571 /// For example, if the local node is subscribed to a certain subject and there are X nodes publishing
569572 /// transfers on that subject, then there will be X sessions created for that subject.
570573 ///
571- /// Each session instance takes sizeof(UdpardInternalRxSession) bytes of dynamic memory for itself,
572- /// which is at most 512 bytes on wide-word platforms (on small word size platforms it is usually much smaller).
574+ /// Each session instance takes sizeof(rx_session_t) bytes of dynamic memory for itself.
573575 /// On top of that, each session instance holds memory for the transfer payload fragments and small fixed-size
574576 /// metadata objects called "fragment handles" (at most 128 bytes large, usually much smaller,
575577 /// depending on the pointer width and the word size), one handle per fragment.
@@ -607,7 +609,8 @@ typedef struct udpard_rx_port_t
607609} udpard_rx_port_t ;
608610
609611/// Represents a received Cyphal transfer.
610- /// The payload is owned by this instance, so the application must free it after use; see udpardRxTransferFree.
612+ /// The payload is owned by this instance, so the application must free it after use using udpard_fragment_free_all()
613+ /// together with the port's fragment memory resource.
611614typedef struct udpard_rx_transfer_t
612615{
613616 udpard_us_t timestamp ;
@@ -717,11 +720,11 @@ void udpard_rx_free(udpard_rx_t* const self);
717720void udpard_rx_poll (udpard_rx_t * const self , const udpard_us_t now );
718721
719722/// To subscribe to a subject, the application should do this:
720- /// 1. Create a new udpard_rx_subscription_t instance using udpard_rx_subscription_new ().
723+ /// 1. Create a new udpard_rx_port_t instance using udpard_rx_port_new ().
721724/// 2. Per redundant network interface:
722- /// - Create a new RX socket bound to the IP multicast group address and UDP port number specified in the
723- /// endpoint field of the initialized subscription instance .
724- /// 3. Read data from the sockets continuously and forward each datagram to udpard_rx_subscription_receive ,
725+ /// - Create a new RX socket bound to the IP multicast group address and UDP port number returned by
726+ /// udpard_make_subject_endpoint() for the desired subject-ID .
727+ /// 3. Read data from the sockets continuously and forward each datagram to udpard_rx_port_push() ,
725728/// along with the index of the redundant interface the datagram was received on.
726729///
727730/// The extent defines the maximum possible size of received objects, considering also possible future data type
@@ -763,7 +766,7 @@ void udpard_rx_port_free(udpard_rx_t* const rx, udpard_rx_port_t* const port);
763766/// 2. A new transfer fragment handle is allocated when a new transfer fragment is accepted.
764767/// 3. Allocated objects may occasionally be deallocated to clean up stale transfers and sessions.
765768///
766- /// The time complexity is O(log n + log k) where n is the number of remote notes publishing on this subject,
769+ /// The time complexity is O(log n + log k) where n is the number of remote nodes publishing on this subject,
767770/// and k is the number of fragments retained in memory for the corresponding in-progress transfer.
768771/// No data copying takes place.
769772///
0 commit comments