#include "dds_rtf2_dcps.idl" module CCM_DDS { // =================================================================================== // Non-typed part // (here are placed all the constructs that are not dependent on the data type) // =================================================================================== // --------------------------- // Enums, structs and Typedefs // --------------------------- typedef unsigned long DataNumber_t; // count or index of data typedef sequence DataNumberSeq; const DataNumber_t UNLIMITED = 0; enum AccessStatus { FRESH_INFO, ALREADY_SEEN }; enum InstanceStatus { // at sample time, as perceived by the component INSTANCE_CREATED, INSTANCE_FILTERED_IN, INSTANCE_UPDATED, INSTANCE_FILTERED_OUT, INSTANCE_DELETED }; struct ReadInfo { DDS::InstanceHandle_t instance_handle; DDS::Time_t source_timestamp; AccessStatus access_status; InstanceStatus instance_status; }; typedef sequence ReadInfoSeq; struct QueryFilter { string expression; DDS::StringSeq parameters; }; // Data Listener control // --------------------- enum ListenerMode { NOT_ENABLED, ONE_BY_ONE, MANY_BY_MANY }; // ---------- // Exceptions // ---------- exception AlreadyCreated { DataNumberSeq indexes; // of the erroneous }; exception NonExistent{ DataNumberSeq indexes; // of the erroneous }; exception InternalError{ DDS::ReturnCode_t error_code; // DDS codes that are relevant: // ERROR (1); // UNSUPPORTED (2); // BAD_PARAMETER (3) // PRECONDITION_NOT_MET (4) // OUT_OF_RESOURCE (5) DataNumber_t index; // of the erroneous }; exception NonChangeable {}; // ---------- // Interfaces // ---------- // Listener Control // ---------------- local interface DataListenerControl { attribute ListenerMode mode; // default NOT_ENABLED attribute DataNumber_t max_delivered_data; // default 0 (no limit) }; local interface StateListenerControl : DataListenerControl { attribute boolean is_filter_interpreted; // default FALSE }; // Content Filter Parameters Setting // --------------------------------- local interface ContentFilterSetting { void set_filter_parameters (in DDS::StringSeq parameters) raises (InternalError); }; // Status Access // ------------- local interface PortStatusListener { // status that are relevant to the component void on_requested_deadline_missed( in DDS::DataReader the_reader, in DDS::RequestedDeadlineMissedStatus status); void on_sample_lost( in DDS::DataReader the_reader, in DDS::SampleLostStatus status); }; local interface ConnectorStatusListener { // status that are relevant system-wide void on_inconsistent_topic( in DDS::Topic the_topic, in DDS::InconsistentTopicStatus status); void on_requested_incompatible_qos( in DDS::DataReader the_reader, in DDS::RequestedIncompatibleQosStatus status); void on_sample_rejected( in DDS::DataReader the_reader, in DDS::SampleRejectedStatus status); void on_offered_deadline_missed( in DDS::DataWriter the_writer, in DDS::OfferedDeadlineMissedStatus status); void on_offered_incompatible_qos( in DDS::DataWriter the_writer, in DDS::OfferedIncompatibleQosStatus status); void on_unexpected_status ( in DDS::Entity the_entity, in DDS::StatusKind status_kind); }; // --------------- // Connector bases // --------------- connector DDS_Base { uses ConnectorStatusListener error_listener; attribute DDS::DomainId_t domain_id setraises (NonChangeable); attribute string qos_profile // File URL or XML string setraises (NonChangeable); }; connector DDS_TopicBase : DDS_Base { attribute string topic_name setraises (NonChangeable); attribute DDS::StringSeq key_fields setraises (NonChangeable); }; // =================================================================================== // Typed sub-part // (here are placed all the construct that are depending on the data type // either directly or indirectly) // =================================================================================== module Typed TSeq> { // Gathers all the constructs that are dependent on the data type (T), // either directly -- interfaces making use of T or TSeq, // or indirectly -- porttypes using or providing those intefaces. // TSeq is passed as a second parameter to avoid creating a new sequence type. // ------------------------------------- // Interfaces to be 'used' or 'provided' // ------------------------------------- // Data access - publishing side // ----------------------------- // -- InstanceHandle Manager local interface InstanceHandleManager { DDS::InstanceHandle_t register_instance (in T datum) raises (InternalError); void unregister_instance (in T datum, in DDS::InstanceHandle_t instance_handle) raises (InternalError); }; // -- Writer: when the instance lifecycle is not a concern local interface Writer : InstanceHandleManager { void write_one (in T datum, in DDS::InstanceHandle_t instance_handle) raises (InternalError); void write_many (in TSeq data) raises (InternalError); attribute boolean is_coherent_write; // FALSE by default // behavior // --------- // - the handle is exactly managed as by DDS (cf. DDS spec for more details) // - attempt to write_many is stopped at the first error // - if is_coherent_write, DDS write orders issued by a write_many // are placed between begin/end coherent updates (even if an error occurs) }; // -- Updater: when the instance lifecycle is a concern local interface Updater : InstanceHandleManager { void create_one (in T datum) raises (AlreadyCreated, InternalError); void update_one (in T datum, in DDS::InstanceHandle_t instance_handle) raises (NonExistent, InternalError); void delete_one (in T datum,in DDS::InstanceHandle_t instance_handle) raises (NonExistent, InternalError); void create_many (in TSeq data) raises (AlreadyCreated, InternalError); void update_many (in TSeq data) raises (NonExistent, InternalError); void delete_many (in TSeq data) raises (NonExistent, InternalError); attribute boolean is_global_scope // FALSE by default setraises (NonChangeable); attribute boolean is_coherent_write; // FALSE by default // behavior // -------- // - the handle is exactly managed as by DDS (cf. DDS spec for more details) // - exceptions AlreadyCreated or NonExistent are raised at least if a local // conflict exists; in addition if is_global_scope is true, the test on // existence attempts to take into account the instances created outside // - note: this check requires to previously attempt to read (not free) // - note: this check is not 100% guaranteed as a creation or a deletion // may occur in the short time between the check and the DDS order // - For *-many operations: // - global check is performed before actual write or dispose // (in case of error, all the erroneous instances are reported // in the exception) // - attempt to DDS write or dispose is stopped at the first error // - if is_coherent_write, DDS orders resulting from a *_many operation // are placed between begin/end coherent updates (even if an error // occurs) }; // Data access - subscribing side // ------------------------------ // -- Reader: to simply access to the available data (no wait) local interface Reader { void read_last (inout TSeq data, inout ReadInfoSeq infos) raises (InternalError); void read_all (inout TSeq data, inout ReadInfoSeq infos) raises (InternalError); void read_one_last (inout T datum, out ReadInfo info, in DDS::InstanceHandle_t instance_handle) raises (NonExistent, InternalError); void read_one_all (in T datum, inout TSeq data, inout ReadInfoSeq infos, in DDS::InstanceHandle_t instance_handle) raises (NonExistent, InternalError); attribute QueryFilter query setraises (InternalError); // behavior // -------- // - read operations are performed with the following parameters // - READ or NO_READ // - NEW or NOT_NEW // - ALIVE // - through the query as specified ("" expression means no query) // - data returned: // - read_last returns for each living instance, its last sample // - read_all returns all the samples of all instances // ordered by instance first and then by sample // - read_one_last returns the last sample of the given instance // - read_one_all returns all the samples for the given instance // - read_one operations use the instance_handle the same way // the Writer or Updater *_one operations do }; // -- Getter: to get new data (and wait for) local interface Getter { boolean get_one (out T datum, out ReadInfo info) raises (InternalError); boolean get_many (inout TSeq data, inout ReadInfoSeq infos) raises (InternalError); attribute DDS::Duration_t time_out; attribute DataNumber_t max_delivered_data; // default 0 (no limit) // behavior // -------- // - get operations are performed with the following parameters // - NO_READ // - NEW or NOT_NEW // - ALIVE or NOT_ALIVE // - through the query as specified in the associated Reader // - within the time limit specified in time_out // - all operations returns TRUE if data are provided // or FALSE if time-out occurred // - data returned: // - get_one returns each read sample one by one // - get_many returns all available samples within the // max_delivered_data limit }; // -- Listener: similar to a Getter but in push mode local interface Listener { void on_one_data (in T datum, in ReadInfo info); void on_many_data (in TSeq data, in ReadInfoSeq infos); // behavior // -------- // - on_one_data() trigered is the mode of the associated listener control // is ONE_BY_ONE (then similar to a get_one(), except that in push mode // instead of pull mode) // - on_many_data() triggered if the listener mode is MANY_BY_MANY (then // similar to get_many() but in push mode) // - query filter (if any) in the associated Reader }; // -- StateListener: listener to be notified based on the instance lifecycle local interface StateListener { void on_creation (in T datum, in ReadInfo info); void on_one_update (in T datum, in ReadInfo info); void on_many_updates (in TSeq data, in ReadInfoSeq infos); void on_deletion (in T datum, in ReadInfo info); // behavior // -------- // - no operations are trigerred if the mode of the associated listener // control is NOT_ENABLED // - on_creation() is triggered if the instance is considered as new in the // component scope; note that in case there is a filter and the attribute // is_filter_interpreted of the listener control is TRUE, this gathers also // the case when the instance is filtered-in. // - on_delation() is triggered if the instance is no more existing; note // that in case there is a filter and the attribute // is_filter_interpreted of the listener control is TRUE, this gathers // also the case when the instance is filtered-out // - on_one_update() is trigrered if neither on_creation() nor on_deletion() // are triggered and the mode of the associated listener control is // ONE_BY_ONE // - on_many_updates()is triggered if neither on_creation() nor on_deletion() // are triggered and the mode of the associated listener control is // MANY_BY_MANY; the number of returned samples is within the limits of // max_delivered_data attribute of the associated listener control. // - query filter (if any) in the associated Reader }; // --------- // DDS Ports // --------- porttype DDS_Write { uses Writer data; uses DDS::DataWriter dds_entity; }; porttype DDS_Update { uses Updater data; uses DDS::DataWriter dds_entity; }; porttype DDS_Read { uses Reader data; attribute QueryFilter filter setraises(NonChangeable); uses ContentFilterSetting filter_config; uses DDS::DataReader dds_entity; provides PortStatusListener status; }; porttype DDS_Get { uses Reader data; uses Getter fresh_data; attribute QueryFilter filter setraises(NonChangeable); uses ContentFilterSetting filter_config; uses DDS::DataReader dds_entity; provides PortStatusListener status; }; porttype DDS_Listen { uses Reader data; uses DataListenerControl data_control; provides Listener data_listener; attribute QueryFilter filter setraises(NonChangeable); uses ContentFilterSetting filter_config; uses DDS::DataReader dds_entity; provides PortStatusListener status; }; porttype DDS_StateListen { uses Reader data; uses StateListenerControl data_control; provides StateListener data_listener; attribute QueryFilter filter setraises(NonChangeable); uses ContentFilterSetting filter_config; uses DDS::DataReader dds_entity; provides PortStatusListener status; }; // ---------------------------- // Connectors // (Correspond to DDS patterns) // ---------------------------- connector DDS_State : DDS_TopicBase { mirrorport DDS_Update observable; mirrorport DDS_Read passive_observer; mirrorport DDS_Get pull_observer; mirrorport DDS_Listen push_observer; mirrorport DDS_StateListen push_state_observer; }; connector DDS_Event : DDS_TopicBase { mirrorport DDS_Write supplier; mirrorport DDS_Get pull_consumer; mirrorport DDS_Listen push_consumer; }; }; };