File dds_psm_types.hpp

File List > astutedds > dcps > dds_psm_types.hpp

Go to the documentation of this file


#ifndef ASTUTEDDS_DCPS_DDS_PSM_TYPES_HPP
#define ASTUTEDDS_DCPS_DDS_PSM_TYPES_HPP

#include <astutedds/dcps/qos.hpp>
#include <cstdint>
#include <string>
#include <vector>

namespace astutedds::dcps
{

    // Forward declarations of entity classes defined in dcps.hpp
    class Topic;
    class DataWriter;
    class DataReader;
    class Publisher;
    class Subscriber;

    // Forward declaration — full SampleInfo definition is in dcps.hpp
    struct SampleInfo;

    // ========================================================================
    // §2.2.1 - Basic DDS Typedefs
    // ========================================================================

    using InstanceHandle_t = int32_t;
    constexpr InstanceHandle_t HANDLE_NIL = 0;

    using DomainId_t = int32_t;
    using BuiltinTopicKey_t = std::array<int32_t, 3>;
    using StringSeq = std::vector<std::string>;

    // Standard DDS typedefs (required by OMG interop configurator macros)
    using UInt32 = uint32_t;

    // ========================================================================
    // §2.2.2.1 - Return Codes
    // ========================================================================
    // ReturnCode_t is an unscoped enum (not enum class) so that:
    //  - ReturnCode_t::RETCODE_OK  works (scoped access)
    //  - RETCODE_OK                works (unscoped access via using namespace)
    //  - Comparison with int works (implicit conversion)
    // This is required by shape_main.cxx which does:  if (retval == RETCODE_OK)

    enum ReturnCode_t : int32_t
    {
        RETCODE_OK                  = 0,
        RETCODE_ERROR               = 1,
        RETCODE_UNSUPPORTED         = 2,
        RETCODE_BAD_PARAMETER       = 3,
        RETCODE_PRECONDITION_NOT_MET = 4,
        RETCODE_OUT_OF_RESOURCES    = 5,
        RETCODE_NOT_ENABLED         = 6,
        RETCODE_IMMUTABLE_POLICY    = 7,
        RETCODE_INCONSISTENT_POLICY = 8,
        RETCODE_ALREADY_DELETED     = 9,
        RETCODE_TIMEOUT             = 10,
        RETCODE_NO_DATA             = 11,
        RETCODE_ILLEGAL_OPERATION   = 12
    };

    // ========================================================================
    // §2.2.2.2 - Special Constants
    // ========================================================================

    constexpr int32_t LENGTH_UNLIMITED = -1;
    constexpr InstanceHandle_t HANDLE_NIL_VALUE = 0;

    // ========================================================================
    // §2.2.3 - QoS Policy Kind Constants (bare / unscoped)
    //
    // These duplicate the scoped enum values for OMG PSM compatibility.
    // Code can use either style:
    //   DDS::VOLATILE_DURABILITY_QOS            (bare)
    //   DDS::DurabilityQosPolicyKind::VOLATILE  (scoped)
    // ========================================================================

    // Durability
    constexpr auto VOLATILE_DURABILITY_QOS        = DurabilityQosPolicyKind::VOLATILE_DURABILITY_QOS;
    constexpr auto TRANSIENT_LOCAL_DURABILITY_QOS = DurabilityQosPolicyKind::TRANSIENT_LOCAL_DURABILITY_QOS;
    constexpr auto TRANSIENT_DURABILITY_QOS       = DurabilityQosPolicyKind::TRANSIENT_DURABILITY_QOS;
    constexpr auto PERSISTENT_DURABILITY_QOS      = DurabilityQosPolicyKind::PERSISTENT_DURABILITY_QOS;

    // Reliability
    constexpr auto BEST_EFFORT_RELIABILITY_QOS    = ReliabilityQosPolicyKind::BEST_EFFORT_RELIABILITY_QOS;
    constexpr auto RELIABLE_RELIABILITY_QOS       = ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS;

    // History
    constexpr auto KEEP_LAST_HISTORY_QOS          = HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS;
    constexpr auto KEEP_ALL_HISTORY_QOS           = HistoryQosPolicyKind::KEEP_ALL_HISTORY_QOS;

    // Ownership
    constexpr auto SHARED_OWNERSHIP_QOS           = OwnershipQosPolicyKind::SHARED_OWNERSHIP_QOS;
    constexpr auto EXCLUSIVE_OWNERSHIP_QOS        = OwnershipQosPolicyKind::EXCLUSIVE_OWNERSHIP_QOS;

    // Liveliness
    constexpr auto AUTOMATIC_LIVELINESS_QOS              = LivelinessQosPolicyKind::AUTOMATIC_LIVELINESS_QOS;
    constexpr auto MANUAL_BY_PARTICIPANT_LIVELINESS_QOS  = LivelinessQosPolicyKind::MANUAL_BY_PARTICIPANT_LIVELINESS_QOS;
    constexpr auto MANUAL_BY_TOPIC_LIVELINESS_QOS        = LivelinessQosPolicyKind::MANUAL_BY_TOPIC_LIVELINESS_QOS;

    // Destination Order
    constexpr auto BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS = DestinationOrderQosPolicyKind::BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS;
    constexpr auto BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS    = DestinationOrderQosPolicyKind::BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS;

    // Presentation Access Scope
    constexpr auto INSTANCE_PRESENTATION_QOS      = PresentationQosPolicyAccessScopeKind::INSTANCE_PRESENTATION_QOS;
    constexpr auto TOPIC_PRESENTATION_QOS         = PresentationQosPolicyAccessScopeKind::TOPIC_PRESENTATION_QOS;
    constexpr auto GROUP_PRESENTATION_QOS         = PresentationQosPolicyAccessScopeKind::GROUP_PRESENTATION_QOS;

    // ========================================================================
    // §7.6.3.5 - Data Representation IDs (XTypes)
    // ========================================================================

    using DataRepresentationId_t = int16_t;

    constexpr DataRepresentationId_t XCDR_DATA_REPRESENTATION  = 0;
    constexpr DataRepresentationId_t XML_DATA_REPRESENTATION   = 1;
    constexpr DataRepresentationId_t XCDR2_DATA_REPRESENTATION = 2;

    using DataRepresentationIdSeq = std::vector<DataRepresentationId_t>;

    // ========================================================================
    // §2.2.3 - QoS Policy ID Constants
    // ========================================================================

    using QosPolicyId_t = int32_t;

    constexpr QosPolicyId_t INVALID_QOS_POLICY_ID                = 0;
    constexpr QosPolicyId_t USERDATA_QOS_POLICY_ID               = 1;
    constexpr QosPolicyId_t DURABILITY_QOS_POLICY_ID             = 2;
    constexpr QosPolicyId_t PRESENTATION_QOS_POLICY_ID           = 3;
    constexpr QosPolicyId_t DEADLINE_QOS_POLICY_ID               = 4;
    constexpr QosPolicyId_t LATENCYBUDGET_QOS_POLICY_ID          = 5;
    constexpr QosPolicyId_t OWNERSHIP_QOS_POLICY_ID              = 6;
    constexpr QosPolicyId_t OWNERSHIPSTRENGTH_QOS_POLICY_ID      = 7;
    constexpr QosPolicyId_t LIVELINESS_QOS_POLICY_ID             = 8;
    constexpr QosPolicyId_t TIMEBASEDFILTER_QOS_POLICY_ID        = 9;
    constexpr QosPolicyId_t PARTITION_QOS_POLICY_ID              = 10;
    constexpr QosPolicyId_t RELIABILITY_QOS_POLICY_ID            = 11;
    constexpr QosPolicyId_t DESTINATIONORDER_QOS_POLICY_ID       = 12;
    constexpr QosPolicyId_t HISTORY_QOS_POLICY_ID                = 13;
    constexpr QosPolicyId_t RESOURCELIMITS_QOS_POLICY_ID         = 14;
    constexpr QosPolicyId_t ENTITYFACTORY_QOS_POLICY_ID          = 15;
    constexpr QosPolicyId_t WRITERDATALIFECYCLE_QOS_POLICY_ID    = 16;
    constexpr QosPolicyId_t READERDATALIFECYCLE_QOS_POLICY_ID    = 17;
    constexpr QosPolicyId_t TOPICDATA_QOS_POLICY_ID              = 18;
    constexpr QosPolicyId_t GROUPDATA_QOS_POLICY_ID              = 19;
    constexpr QosPolicyId_t TRANSPORTPRIORITY_QOS_POLICY_ID      = 20;
    constexpr QosPolicyId_t LIFESPAN_QOS_POLICY_ID               = 21;
    constexpr QosPolicyId_t DURABILITYSERVICE_QOS_POLICY_ID      = 22;
    constexpr QosPolicyId_t DATAREPRESENTATION_QOS_POLICY_ID     = 23;    constexpr QosPolicyId_t DATA_REPRESENTATION_QOS_POLICY_ID  = 23; // alias    constexpr QosPolicyId_t TYPEENFORCEMENT_QOS_POLICY_ID        = 24;

    // ========================================================================
    // §2.2.2.5 - Duration_t
    //
    // The RTPS layer uses rtps::Time_t / rtps::Duration_t (seconds + fraction).
    // The DDS PSM uses Duration_t with {sec, nanosec}.
    // We provide a DDS-style Duration_t here that wraps the RTPS one.
    // ========================================================================

    struct Duration_t
    {
        int32_t sec{0};
        uint32_t nanosec{0};

        constexpr Duration_t() = default;
        constexpr Duration_t(int32_t s, uint32_t ns) : sec(s), nanosec(ns) {}

        static Duration_t from_rtps(const rtps::Duration_t &d)
        {
            uint32_t ns = static_cast<uint32_t>(
                static_cast<uint64_t>(d.fraction) * 1000000000ULL / 0x100000000ULL);
            return Duration_t{d.seconds, ns};
        }

        rtps::Duration_t to_rtps() const
        {
            uint32_t frac = static_cast<uint32_t>(
                static_cast<uint64_t>(nanosec) * 0x100000000ULL / 1000000000ULL);
            return rtps::Duration_t{sec, frac};
        }

        static constexpr Duration_t DURATION_INFINITE()
        {
            return Duration_t{0x7fffffff, 0x7fffffff};
        }

        static constexpr Duration_t DURATION_ZERO()
        {
            return Duration_t{0, 0};
        }
    };

    // ========================================================================
    // §2.2.2.3 - Time_t (DDS-layer)
    // ========================================================================

    struct DdsTime_t
    {
        int32_t sec{0};
        uint32_t nanosec{0};
    };

    // ========================================================================
    // §2.2.4.1 - Sample State
    // ========================================================================

    using SampleStateKind = uint32_t;

    constexpr SampleStateKind READ_SAMPLE_STATE     = 0x0001u;
    constexpr SampleStateKind NOT_READ_SAMPLE_STATE = 0x0002u;

    using SampleStateMask = uint32_t;
    constexpr SampleStateMask ANY_SAMPLE_STATE      = 0xFFFFu;

    // ========================================================================
    // §2.2.4.2 - View State
    // ========================================================================

    using ViewStateKind = uint32_t;

    constexpr ViewStateKind NEW_VIEW_STATE           = 0x0001u;
    constexpr ViewStateKind NOT_NEW_VIEW_STATE       = 0x0002u;

    using ViewStateMask = uint32_t;
    constexpr ViewStateMask ANY_VIEW_STATE           = 0xFFFFu;

    // ========================================================================
    // §2.2.4.3 - Instance State
    // ========================================================================

    using InstanceStateKind = uint32_t;

    constexpr InstanceStateKind ALIVE_INSTANCE_STATE                = 0x0001u;
    constexpr InstanceStateKind NOT_ALIVE_DISPOSED_INSTANCE_STATE   = 0x0002u;
    constexpr InstanceStateKind NOT_ALIVE_NO_WRITERS_INSTANCE_STATE = 0x0004u;

    using InstanceStateMask = uint32_t;
    constexpr InstanceStateMask ANY_INSTANCE_STATE                  = 0xFFFFu;
    constexpr InstanceStateMask NOT_ALIVE_INSTANCE_STATE            = 0x0006u;

    // ========================================================================
    // §2.2.4 - Status Types
    // ========================================================================

    struct QosPolicyCount
    {
        QosPolicyId_t policy_id{INVALID_QOS_POLICY_ID};
        int32_t count{0};
    };

    using QosPolicyCountSeq = std::vector<QosPolicyCount>;

    struct InconsistentTopicStatus
    {
        int32_t total_count{0};
        int32_t total_count_change{0};
    };

    struct SampleLostStatus
    {
        int32_t total_count{0};
        int32_t total_count_change{0};
    };

    struct SampleRejectedStatusKind
    {
        static constexpr int32_t NOT_REJECTED                             = 0;
        static constexpr int32_t REJECTED_BY_INSTANCES_LIMIT              = 1;
        static constexpr int32_t REJECTED_BY_SAMPLES_LIMIT               = 2;
        static constexpr int32_t REJECTED_BY_SAMPLES_PER_INSTANCE_LIMIT  = 3;
    };

    struct SampleRejectedStatus
    {
        int32_t total_count{0};
        int32_t total_count_change{0};
        int32_t last_reason{SampleRejectedStatusKind::NOT_REJECTED};
        InstanceHandle_t last_instance_handle{HANDLE_NIL_VALUE};
    };

    struct LivelinessLostStatus
    {
        int32_t total_count{0};
        int32_t total_count_change{0};
    };

    struct LivelinessChangedStatus
    {
        int32_t alive_count{0};
        int32_t not_alive_count{0};
        int32_t alive_count_change{0};
        int32_t not_alive_count_change{0};
        InstanceHandle_t last_publication_handle{HANDLE_NIL_VALUE};
    };

    struct OfferedDeadlineMissedStatus
    {
        int32_t total_count{0};
        int32_t total_count_change{0};
        InstanceHandle_t last_instance_handle{HANDLE_NIL_VALUE};
    };

    struct RequestedDeadlineMissedStatus
    {
        int32_t total_count{0};
        int32_t total_count_change{0};
        InstanceHandle_t last_instance_handle{HANDLE_NIL_VALUE};
    };

    struct OfferedIncompatibleQosStatus
    {
        int32_t total_count{0};
        int32_t total_count_change{0};
        QosPolicyId_t last_policy_id{INVALID_QOS_POLICY_ID};
        QosPolicyCountSeq policies;
    };

    struct RequestedIncompatibleQosStatus
    {
        int32_t total_count{0};
        int32_t total_count_change{0};
        QosPolicyId_t last_policy_id{INVALID_QOS_POLICY_ID};
        QosPolicyCountSeq policies;
    };

    struct PublicationMatchedStatus
    {
        int32_t total_count{0};
        int32_t total_count_change{0};
        int32_t current_count{0};
        int32_t current_count_change{0};
        InstanceHandle_t last_subscription_handle{HANDLE_NIL_VALUE};
    };

    struct SubscriptionMatchedStatus
    {
        int32_t total_count{0};
        int32_t total_count_change{0};
        int32_t current_count{0};
        int32_t current_count_change{0};
        InstanceHandle_t last_publication_handle{HANDLE_NIL_VALUE};
    };

    // ========================================================================
    // §2.2.4 - Status Masks
    // ========================================================================

    using StatusMask = uint32_t;

    constexpr StatusMask INCONSISTENT_TOPIC_STATUS         = 0x0001u;
    constexpr StatusMask OFFERED_DEADLINE_MISSED_STATUS     = 0x0002u;
    constexpr StatusMask REQUESTED_DEADLINE_MISSED_STATUS   = 0x0004u;
    constexpr StatusMask OFFERED_INCOMPATIBLE_QOS_STATUS    = 0x0020u;
    constexpr StatusMask REQUESTED_INCOMPATIBLE_QOS_STATUS  = 0x0040u;
    constexpr StatusMask SAMPLE_LOST_STATUS                = 0x0080u;
    constexpr StatusMask SAMPLE_REJECTED_STATUS            = 0x0100u;
    constexpr StatusMask DATA_ON_READERS_STATUS            = 0x0200u;
    constexpr StatusMask DATA_AVAILABLE_STATUS             = 0x0400u;
    constexpr StatusMask LIVELINESS_LOST_STATUS            = 0x0800u;
    constexpr StatusMask LIVELINESS_CHANGED_STATUS         = 0x1000u;
    constexpr StatusMask PUBLICATION_MATCHED_STATUS         = 0x2000u;
    constexpr StatusMask SUBSCRIPTION_MATCHED_STATUS        = 0x4000u;
    constexpr StatusMask STATUS_MASK_NONE                  = 0x0000u;
    constexpr StatusMask STATUS_MASK_ALL                   = 0xFFFFFFFFu;

    // ========================================================================
    // Default QoS sentinel values
    // ========================================================================

    // These are extern-declared sentinels. shape_main.cxx passes them to
    // create_* calls to mean "use defaults". We define them as constexpr
    // default-constructed QoS structs.

    inline const DomainParticipantQos PARTICIPANT_QOS_DEFAULT{};
    inline const TopicQos TOPIC_QOS_DEFAULT{};
    inline const PublisherQos PUBLISHER_QOS_DEFAULT{};
    inline const SubscriberQos SUBSCRIBER_QOS_DEFAULT{};
    inline const DataWriterQos DATAWRITER_QOS_DEFAULT{};
    inline const DataReaderQos DATAREADER_QOS_DEFAULT{};

    // ========================================================================
    // Listener base classes (stubs for Phase 1)
    // ========================================================================

    class Listener
    {
    public:
        virtual ~Listener() = default;
    };

    class TopicListener : public Listener
    {
    public:
        virtual void on_inconsistent_topic(Topic * /*topic*/,
                                           const InconsistentTopicStatus & /*status*/) {}
    };

    class DataWriterListener : public Listener
    {
    public:
        virtual void on_offered_deadline_missed(DataWriter * /*writer*/,
                                                const OfferedDeadlineMissedStatus & /*status*/) {}
        virtual void on_offered_incompatible_qos(DataWriter * /*writer*/,
                                                 const OfferedIncompatibleQosStatus & /*status*/) {}
        virtual void on_liveliness_lost(DataWriter * /*writer*/,
                                        const LivelinessLostStatus & /*status*/) {}
        virtual void on_publication_matched(DataWriter * /*writer*/,
                                            const PublicationMatchedStatus & /*status*/) {}
    };

    class DataReaderListener : public Listener
    {
    public:
        virtual void on_requested_deadline_missed(DataReader * /*reader*/,
                                                  const RequestedDeadlineMissedStatus & /*status*/) {}
        virtual void on_requested_incompatible_qos(DataReader * /*reader*/,
                                                   const RequestedIncompatibleQosStatus & /*status*/) {}
        virtual void on_sample_rejected(DataReader * /*reader*/,
                                        const SampleRejectedStatus & /*status*/) {}
        virtual void on_liveliness_changed(DataReader * /*reader*/,
                                           const LivelinessChangedStatus & /*status*/) {}
        virtual void on_data_available(DataReader * /*reader*/) {}
        virtual void on_subscription_matched(DataReader * /*reader*/,
                                             const SubscriptionMatchedStatus & /*status*/) {}
        virtual void on_sample_lost(DataReader * /*reader*/,
                                    const SampleLostStatus & /*status*/) {}
    };

    class SubscriberListener : public DataReaderListener
    {
    public:
        virtual void on_data_on_readers(Subscriber * /*subscriber*/) {}
    };

    class PublisherListener : public DataWriterListener
    {
    };

    class DomainParticipantListener : public Listener
    {
    public:
        // All 13 callbacks required by shape_main.cxx DPListener.
        // Default implementations are empty (no-op).

        // --- TopicListener ---
        virtual void on_inconsistent_topic(Topic * /*topic*/,
                                           const InconsistentTopicStatus & /*status*/) {}

        // --- DataWriterListener ---
        virtual void on_offered_incompatible_qos(DataWriter * /*writer*/,
                                                 const OfferedIncompatibleQosStatus & /*status*/) {}
        virtual void on_publication_matched(DataWriter * /*writer*/,
                                            const PublicationMatchedStatus & /*status*/) {}
        virtual void on_offered_deadline_missed(DataWriter * /*writer*/,
                                                const OfferedDeadlineMissedStatus & /*status*/) {}
        virtual void on_liveliness_lost(DataWriter * /*writer*/,
                                        const LivelinessLostStatus & /*status*/) {}

        // --- DataReaderListener ---
        virtual void on_requested_incompatible_qos(DataReader * /*reader*/,
                                                   const RequestedIncompatibleQosStatus & /*status*/) {}
        virtual void on_subscription_matched(DataReader * /*reader*/,
                                             const SubscriptionMatchedStatus & /*status*/) {}
        virtual void on_requested_deadline_missed(DataReader * /*reader*/,
                                                  const RequestedDeadlineMissedStatus & /*status*/) {}
        virtual void on_liveliness_changed(DataReader * /*reader*/,
                                           const LivelinessChangedStatus & /*status*/) {}
        virtual void on_sample_rejected(DataReader * /*reader*/,
                                        const SampleRejectedStatus & /*status*/) {}
        virtual void on_data_available(DataReader * /*reader*/) {}
        virtual void on_sample_lost(DataReader * /*reader*/,
                                    const SampleLostStatus & /*status*/) {}

        // --- SubscriberListener ---
        virtual void on_data_on_readers(Subscriber * /*subscriber*/) {}
    };

    // ========================================================================
    // SampleInfo sequence (for batch read/take)
    // ========================================================================

    using SampleInfoSeq = std::vector<SampleInfo>;

} // namespace astutedds::dcps

#endif // ASTUTEDDS_DCPS_DDS_PSM_TYPES_HPP