Skip to content

Commit 8751e8e

Browse files
doc review
1 parent 64b3e86 commit 8751e8e

File tree

1 file changed

+39
-36
lines changed

1 file changed

+39
-36
lines changed

libudpard/udpard.h

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
377380
bool 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.
611614
typedef struct udpard_rx_transfer_t
612615
{
613616
udpard_us_t timestamp;
@@ -717,11 +720,11 @@ void udpard_rx_free(udpard_rx_t* const self);
717720
void 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

Comments
 (0)