@@ -568,7 +568,8 @@ typedef struct udpard_rx_memory_resources_t
568568/// This type represents an open input port, such as a subscription to a topic.
569569typedef struct udpard_rx_port_t
570570{
571- uint64_t topic_hash ; ///< Mismatch will be filtered out.
571+ /// Mismatch will be filtered out and the collision notification callback invoked.
572+ uint64_t topic_hash ;
572573
573574 /// Transfer payloads exceeding this extent may be truncated.
574575 /// The total size of the received payload may still exceed this extent setting by some small margin.
@@ -619,17 +620,6 @@ typedef struct udpard_rx_port_t
619620 bool invoked ;
620621} udpard_rx_port_t ;
621622
622- typedef struct udpard_rx_subscription_t
623- {
624- udpard_rx_port_t base ; ///< Always the first member to ensure pointer equivalence.
625-
626- uint32_t subject_id ;
627-
628- /// The IP multicast group address and the UDP port number where UDP/IP datagrams matching this Cyphal
629- /// subject will be sent by the publishers (remote nodes). READ-ONLY
630- udpard_udpip_ep_t mcast_ep ;
631- } udpard_rx_subscription_t ;
632-
633623/// Represents a received Cyphal transfer.
634624/// The payload is owned by this instance, so the application must free it after use; see udpardRxTransferFree.
635625typedef struct udpard_rx_transfer_t
@@ -675,7 +665,6 @@ typedef struct udpard_rx_ack_mandate_t
675665 udpard_prio_t priority ;
676666 uint64_t transfer_id ;
677667 udpard_remote_t remote ;
678-
679668 /// View of the first <=MTU bytes of the transfer payload that is being confirmed.
680669 /// Valid until return from the callback.
681670 udpard_bytes_t payload_head ;
@@ -684,16 +673,17 @@ typedef struct udpard_rx_ack_mandate_t
684673struct udpard_rx_t ;
685674
686675/// A new message is received from a topic, or a P2P message is received.
687- /// The subscription is NULL for P2P transfers.
688676/// The handler takes ownership of the payload; it must free it after use.
689- typedef void (* udpard_rx_on_message_t )(struct udpard_rx_t * , udpard_rx_subscription_t * , udpard_rx_transfer_t );
677+ /// For P2P transfers, the p2p_port of udpard_rx_t is passed as the port argument.
678+ typedef void (* udpard_rx_on_message_t )(struct udpard_rx_t * , udpard_rx_port_t * , udpard_rx_transfer_t );
690679
691680/// A topic hash collision is detected on a topic.
692- typedef void (* udpard_rx_on_collision_t )(struct udpard_rx_t * , udpard_rx_subscription_t * , udpard_remote_t );
681+ /// For P2P transfers, the p2p_port of udpard_rx_t is passed as the port argument.
682+ typedef void (* udpard_rx_on_collision_t )(struct udpard_rx_t * , udpard_rx_port_t * , udpard_remote_t );
693683
694684/// The application is required to send an acknowledgment back to the sender.
695- /// The subscription is NULL for P2P transfers .
696- typedef void (* udpard_rx_on_ack_mandate_t )(struct udpard_rx_t * , udpard_rx_subscription_t * , udpard_rx_ack_mandate_t );
685+ /// For P2P transfers, the p2p_port of udpard_rx_t is passed as the port argument .
686+ typedef void (* udpard_rx_on_ack_mandate_t )(struct udpard_rx_t * , udpard_rx_port_t * , udpard_rx_ack_mandate_t );
697687
698688typedef struct udpard_rx_t
699689{
@@ -715,7 +705,10 @@ typedef struct udpard_rx_t
715705
716706/// The extent of the P2P port is set to SIZE_MAX by default (no truncation at all).
717707/// The application can alter it via udpard_rx_t::p2p_port.extent at any moment if needed; it takes effect immediately
718- /// but may in some cases cause in-progress transfers to be lost if increased updated mid-transfer.
708+ /// but may in some cases cause in-progress transfers to be lost if increased mid-transfer.
709+ ///
710+ /// To free a udpard_rx_t instance, the application must simply free all its ports using udpard_rx_port_free().
711+ /// The RX instance will be safe to discard afterward.
719712///
720713/// True on success, false if any of the arguments are invalid.
721714bool udpard_rx_new (udpard_rx_t * const self ,
@@ -727,7 +720,7 @@ bool udpard_rx_new(udpard_rx_t* const self,
727720
728721/// Must be invoked at least every few milliseconds (more often is fine) to purge timed-out sessions and eject
729722/// received transfers when the reordering window expires. If this is invoked simultaneously with rx subscription
730- /// reception, then this function should be invoked after the reception handling.
723+ /// reception, then this function should ideally be invoked after the reception handling.
731724/// The time complexity is logarithmic in the number of living sessions.
732725void udpard_rx_poll (udpard_rx_t * const self , const udpard_us_t now );
733726
@@ -752,14 +745,17 @@ void udpard_rx_poll(udpard_rx_t* const self, const udpard_us_t now);
752745///
753746/// The return value is true on success, false if any of the arguments are invalid.
754747/// The time complexity is constant. This function does not invoke the dynamic memory manager.
755- bool udpard_rx_subscription_new (udpard_rx_subscription_t * const self ,
756- const uint32_t subject_id ,
757- const uint64_t topic_hash ,
758- const size_t extent ,
759- udpard_us_t reordering_window ,
760- const udpard_rx_memory_resources_t memory );
761-
762- void udpard_rx_subscription_free (udpard_rx_subscription_t * const self );
748+ bool udpard_rx_port_new (udpard_rx_port_t * const self ,
749+ const uint64_t topic_hash ,
750+ const size_t extent ,
751+ const udpard_us_t reordering_window ,
752+ const udpard_rx_memory_resources_t memory );
753+
754+ /// Returns all memory allocated for the sessions, slots, fragments, etc of the given port.
755+ /// Does not free the port itself and does not alter the RX instance aside from unlinking the port from it.
756+ /// It is safe to invoke this at any time, but the port instance shall not be used again unless re-initialized.
757+ /// The function has no effect if any of the arguments are NULL.
758+ void udpard_rx_port_free (udpard_rx_t * const rx , udpard_rx_port_t * const port );
763759
764760/// The timestamp value indicates the arrival time of the datagram. Often, naive software timestamping is adequate
765761/// for these purposes, but some applications may require a greater accuracy (e.g., for time synchronization).
@@ -771,37 +767,22 @@ void udpard_rx_subscription_free(udpard_rx_subscription_t* const self);
771767/// any of the arguments are invalid; the function returns false in that case and the caller must clean up.
772768///
773769/// The function invokes the dynamic memory manager in the following cases only (refer to udpard_rx_port_t):
774- ///
775- /// 1. A new session state instance is allocated when a new session is initiated.
776- ///
777- /// 2. A new transfer fragment handle is allocated when a new transfer fragment is accepted.
778- ///
779- /// 3. Allocated objects may occasionally be deallocated to clean up stale transfers and sessions when publishers
780- /// disappear. This behavior does not increase the worst case execution time and does not improve the worst
781- /// case memory consumption, so a deterministic application need not consider this behavior in its resource
782- /// analysis. This behavior is implemented for the benefit of applications where rigorous characterization is
783- /// unnecessary.
770+ /// 1. A new session state instance is allocated when a new session is initiated.
771+ /// 2. A new transfer fragment handle is allocated when a new transfer fragment is accepted.
772+ /// 3. Allocated objects may occasionally be deallocated to clean up stale transfers and sessions.
784773///
785774/// The time complexity is O(log n + log k) where n is the number of remote notes publishing on this subject (topic),
786775/// and k is the number of fragments retained in memory for the corresponding in-progress transfer.
787776/// No data copying takes place.
788777///
789778/// Returns true on successful processing, false if any of the arguments are invalid.
790- bool udpard_rx_subscription_receive (udpard_rx_t * const rx ,
791- udpard_rx_subscription_t * const sub ,
792- const udpard_us_t timestamp ,
793- const udpard_udpip_ep_t source_endpoint ,
794- const udpard_bytes_mut_t datagram_payload ,
795- const udpard_mem_deleter_t payload_deleter ,
796- const uint_fast8_t redundant_iface_index );
797-
798- /// Like the above but for P2P unicast transfers exchanged between specific nodes.
799- bool udpard_rx_p2p_receive (udpard_rx_t * const rx ,
800- const udpard_us_t timestamp ,
801- const udpard_udpip_ep_t source_endpoint ,
802- const udpard_bytes_mut_t datagram_payload ,
803- const udpard_mem_deleter_t payload_deleter ,
804- const uint_fast8_t redundant_iface_index );
779+ bool udpard_rx_port_push (udpard_rx_t * const rx ,
780+ udpard_rx_port_t * const port ,
781+ const udpard_us_t timestamp ,
782+ const udpard_udpip_ep_t source_ep ,
783+ const udpard_bytes_mut_t datagram_payload ,
784+ const udpard_mem_deleter_t payload_deleter ,
785+ const uint_fast8_t redundant_iface_index );
805786
806787#ifdef __cplusplus
807788}
0 commit comments