diff --git a/src/core/ddsc/CMakeLists.txt b/src/core/ddsc/CMakeLists.txt index 571e2fb..f9c5ff4 100644 --- a/src/core/ddsc/CMakeLists.txt +++ b/src/core/ddsc/CMakeLists.txt @@ -89,12 +89,6 @@ target_include_directories(ddsc PUBLIC "$") -# Generate builtin-topic sources -set(IDLC_ARGS "-dll" "FOO,ddsc/dds_export.h") -idlc_generate(BuiltinTypes ddsc/src/dds_dcps_builtintopics.idl ddsc/src/dds_builtinTopics.idl) -set(IDLC_ARGS) -target_link_libraries(ddsc PRIVATE BuiltinTypes) - target_include_directories(ddsc PUBLIC "$") @@ -127,13 +121,6 @@ install( DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/ddsc" COMPONENT dev) -install( - FILES - "${CMAKE_CURRENT_BINARY_DIR}/dds_dcps_builtintopics.h" - "${CMAKE_CURRENT_BINARY_DIR}/dds_builtinTopics.h" - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/ddsc" - COMPONENT dev) - # TODO: improve test inclusion. if((BUILD_TESTING) AND ((NOT DEFINED MSVC_VERSION) OR (MSVC_VERSION GREATER "1800"))) add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/tests") diff --git a/src/core/ddsc/include/ddsc/dds.h b/src/core/ddsc/include/ddsc/dds.h index d407d95..87f264e 100644 --- a/src/core/ddsc/include/ddsc/dds.h +++ b/src/core/ddsc/include/ddsc/dds.h @@ -48,7 +48,6 @@ typedef _Return_type_success_(return > 0) int32_t dds_entity_t; #include "ddsc/dds_public_error.h" #include "ddsc/dds_public_status.h" #include "ddsc/dds_public_listener.h" -#include "dds_dcps_builtintopics.h" #if defined (__cplusplus) extern "C" { @@ -74,15 +73,9 @@ DDS_EXPORT dds_domainid_t dds_domain_default (void); * @{ */ extern DDS_EXPORT const dds_entity_t DDS_BUILTIN_TOPIC_DCPSPARTICIPANT; -extern DDS_EXPORT const dds_entity_t DDS_BUILTIN_TOPIC_CMPARTICIPANT; -extern DDS_EXPORT const dds_entity_t DDS_BUILTIN_TOPIC_DCPSTYPE; extern DDS_EXPORT const dds_entity_t DDS_BUILTIN_TOPIC_DCPSTOPIC; extern DDS_EXPORT const dds_entity_t DDS_BUILTIN_TOPIC_DCPSPUBLICATION; -extern DDS_EXPORT const dds_entity_t DDS_BUILTIN_TOPIC_CMPUBLISHER; extern DDS_EXPORT const dds_entity_t DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION; -extern DDS_EXPORT const dds_entity_t DDS_BUILTIN_TOPIC_CMSUBSCRIBER; -extern DDS_EXPORT const dds_entity_t DDS_BUILTIN_TOPIC_CMDATAWRITER; -extern DDS_EXPORT const dds_entity_t DDS_BUILTIN_TOPIC_CMDATAREADER; /** @}*/ /** @name Communication Status definitions diff --git a/src/core/ddsc/include/ddsc/dds_public_qos.h b/src/core/ddsc/include/ddsc/dds_public_qos.h index 64a7e4e..b7f2243 100644 --- a/src/core/ddsc/include/ddsc/dds_public_qos.h +++ b/src/core/ddsc/include/ddsc/dds_public_qos.h @@ -545,14 +545,10 @@ void dds_qset_durability_service * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] value - Pointer that will store the userdata * @param[in,out] sz - Pointer that will store the size of userdata + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_userdata -( - _In_ const dds_qos_t * __restrict qos, - _Outptr_result_bytebuffer_maybenull_(*sz) void ** value, - _Out_ size_t * sz -); +DDS_EXPORT bool dds_qget_userdata (const dds_qos_t * __restrict qos, void **value, size_t *sz); /** * @brief Get the topicdata from a qos structure @@ -560,14 +556,10 @@ void dds_qget_userdata * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] value - Pointer that will store the topicdata * @param[in,out] sz - Pointer that will store the size of topicdata - */ -DDS_EXPORT -void dds_qget_topicdata -( - _In_ const dds_qos_t * __restrict qos, - _Outptr_result_bytebuffer_maybenull_(*sz) void ** value, - _Out_ size_t * sz -); + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object +*/ +DDS_EXPORT bool dds_qget_topicdata (const dds_qos_t * __restrict qos, void **value, size_t *sz); /** * @brief Get the groupdata from a qos structure @@ -575,27 +567,20 @@ void dds_qget_topicdata * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] value - Pointer that will store the groupdata * @param[in,out] sz - Pointer that will store the size of groupdata + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_groupdata -( - _In_ const dds_qos_t * __restrict qos, - _Outptr_result_bytebuffer_maybenull_(*sz) void ** value, - _Out_ size_t * sz -); +DDS_EXPORT bool dds_qget_groupdata (const dds_qos_t * __restrict qos, void **value, size_t *sz); /** * @brief Get the durability policy from a qos structure * * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] kind - Pointer that will store the durability kind + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_durability -( - _In_ const dds_qos_t * __restrict qos, - _Out_ dds_durability_kind_t *kind -); +DDS_EXPORT bool dds_qget_durability (const dds_qos_t * __restrict qos, dds_durability_kind_t *kind); /** * @brief Get the history policy from a qos structure @@ -603,14 +588,10 @@ void dds_qget_durability * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] kind - Pointer that will store the history kind (optional) * @param[in,out] depth - Pointer that will store the history depth (optional) + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_history -( - _In_ const dds_qos_t * __restrict qos, - _Out_opt_ dds_history_kind_t * kind, - _Out_opt_ int32_t *depth -); +DDS_EXPORT bool dds_qget_history (const dds_qos_t * __restrict qos, dds_history_kind_t *kind, int32_t *depth); /** * @brief Get the resource-limits policy from a qos structure @@ -619,15 +600,10 @@ void dds_qget_history * @param[in,out] max_samples - Pointer that will store the number of samples resource-limit (optional) * @param[in,out] max_instances - Pointer that will store the number of instances resource-limit (optional) * @param[in,out] max_samples_per_instance - Pointer that will store the number of samples per instance resource-limit (optional) + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_resource_limits -( - _In_ const dds_qos_t * __restrict qos, - _Out_opt_ int32_t *max_samples, - _Out_opt_ int32_t *max_instances, - _Out_opt_ int32_t *max_samples_per_instance -); +DDS_EXPORT bool dds_qget_resource_limits (const dds_qos_t * __restrict qos, int32_t *max_samples, int32_t *max_instances, int32_t *max_samples_per_instance); /** * @brief Get the presentation policy from a qos structure @@ -636,80 +612,60 @@ void dds_qget_resource_limits * @param[in,out] access_scope - Pointer that will store access scope kind (optional) * @param[in,out] coherent_access - Pointer that will store coherent access enable value (optional) * @param[in,out] ordered_access - Pointer that will store orderede access enable value (optional) + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_presentation -( - _In_ const dds_qos_t * __restrict qos, - _Out_opt_ dds_presentation_access_scope_kind_t *access_scope, - _Out_opt_ bool *coherent_access, - _Out_opt_ bool *ordered_access -); +DDS_EXPORT bool dds_qget_presentation (const dds_qos_t * __restrict qos, dds_presentation_access_scope_kind_t *access_scope, bool *coherent_access, bool *ordered_access); /** * @brief Get the lifespan policy from a qos structure * * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] lifespan - Pointer that will store lifespan duration + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_lifespan -( - _In_ const dds_qos_t * __restrict qos, - _Out_ dds_duration_t * lifespan -); +DDS_EXPORT bool dds_qget_lifespan (const dds_qos_t * __restrict qos, dds_duration_t *lifespan); /** * @brief Get the deadline policy from a qos structure * * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] deadline - Pointer that will store deadline duration + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_deadline -( - _In_ const dds_qos_t * __restrict qos, - _Out_ dds_duration_t * deadline -); +DDS_EXPORT bool dds_qget_deadline (const dds_qos_t * __restrict qos, dds_duration_t *deadline); /** * @brief Get the latency-budget policy from a qos structure * * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] duration - Pointer that will store latency-budget duration + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_latency_budget -( - _In_ const dds_qos_t * __restrict qos, - _Out_ dds_duration_t *duration -); +DDS_EXPORT bool dds_qget_latency_budget (const dds_qos_t * __restrict qos, dds_duration_t *duration); /** * @brief Get the ownership policy from a qos structure * * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] kind - Pointer that will store the ownership kind + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_ownership -( - _In_ const dds_qos_t * __restrict qos, - _Out_ dds_ownership_kind_t *kind -); +DDS_EXPORT bool dds_qget_ownership (const dds_qos_t * __restrict qos, dds_ownership_kind_t *kind); /** * @brief Get the ownership strength qos policy * * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] value - Pointer that will store the ownership strength value + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_ownership_strength -( - _In_ const dds_qos_t * __restrict qos, - _Out_ int32_t *value -); +DDS_EXPORT bool dds_qget_ownership_strength (const dds_qos_t * __restrict qos, int32_t *value); /** * @brief Get the liveliness qos policy @@ -717,27 +673,20 @@ void dds_qget_ownership_strength * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] kind - Pointer that will store the liveliness kind (optional) * @param[in,out] lease_duration - Pointer that will store the liveliness lease duration (optional) + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_liveliness -( - _In_ const dds_qos_t * __restrict qos, - _Out_opt_ dds_liveliness_kind_t *kind, - _Out_opt_ dds_duration_t *lease_duration -); +DDS_EXPORT bool dds_qget_liveliness (const dds_qos_t * __restrict qos, dds_liveliness_kind_t *kind, dds_duration_t *lease_duration); /** * @brief Get the time-based filter qos policy * * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] minimum_separation - Pointer that will store the minimum separation duration (optional) + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_time_based_filter -( - _In_ const dds_qos_t * __restrict qos, - _Out_ dds_duration_t *minimum_separation -); +DDS_EXPORT bool dds_qget_time_based_filter (const dds_qos_t * __restrict qos, dds_duration_t *minimum_separation); /** * @brief Get the partition qos policy @@ -745,14 +694,10 @@ void dds_qget_time_based_filter * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] n - Pointer that will store the number of partitions (optional) * @param[in,out] ps - Pointer that will store the string(s) containing partition name(s) (optional) + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_partition -( - _In_ const dds_qos_t * __restrict qos, - _Out_ uint32_t *n, - _Outptr_opt_result_buffer_all_maybenull_(*n) char *** ps -); +DDS_EXPORT bool dds_qget_partition (const dds_qos_t * __restrict qos, uint32_t *n, char ***ps); /** * @brief Get the reliability qos policy @@ -760,53 +705,40 @@ void dds_qget_partition * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] kind - Pointer that will store the reliability kind (optional) * @param[in,out] max_blocking_time - Pointer that will store the max blocking time for reliable reliability (optional) + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_reliability -( - _In_ const dds_qos_t * __restrict qos, - _Out_opt_ dds_reliability_kind_t *kind, - _Out_opt_ dds_duration_t *max_blocking_time -); +DDS_EXPORT bool dds_qget_reliability (const dds_qos_t * __restrict qos, dds_reliability_kind_t *kind, dds_duration_t *max_blocking_time); /** * @brief Get the transport priority qos policy * * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] value - Pointer that will store the transport priority value + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_transport_priority -( - _In_ const dds_qos_t * __restrict qos, - _Out_ int32_t *value -); +DDS_EXPORT bool dds_qget_transport_priority (const dds_qos_t * __restrict qos, int32_t *value); /** * @brief Get the destination-order qos policy * * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] kind - Pointer that will store the destination-order kind + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_destination_order -( - _In_ const dds_qos_t * __restrict qos, - _Out_ dds_destination_order_kind_t *kind -); +DDS_EXPORT bool dds_qget_destination_order (const dds_qos_t * __restrict qos, dds_destination_order_kind_t *kind); /** * @brief Get the writer data-lifecycle qos policy * * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] autodispose_unregistered_instances - Pointer that will store the autodispose unregistered instances enable value + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_writer_data_lifecycle -( - _In_ const dds_qos_t * __restrict qos, - _Out_ bool * autodispose -); +DDS_EXPORT bool dds_qget_writer_data_lifecycle (const dds_qos_t * __restrict qos, bool *autodispose); /** * @brief Get the reader data-lifecycle qos policy @@ -814,14 +746,10 @@ void dds_qget_writer_data_lifecycle * @param[in] qos - Pointer to a dds_qos_t structure storing the policy * @param[in,out] autopurge_nowriter_samples_delay - Pointer that will store the delay for auto-purging samples from instances in a no-writer state (optional) * @param[in,out] autopurge_disposed_samples_delay - Pointer that will store the delay for auto-purging of disposed instances (optional) + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT -void dds_qget_reader_data_lifecycle -( - _In_ const dds_qos_t * __restrict qos, - _Out_opt_ dds_duration_t *autopurge_nowriter_samples_delay, - _Out_opt_ dds_duration_t *autopurge_disposed_samples_delay -); +DDS_EXPORT bool dds_qget_reader_data_lifecycle (const dds_qos_t * __restrict qos, dds_duration_t *autopurge_nowriter_samples_delay, dds_duration_t *autopurge_disposed_samples_delay); /** * @brief Get the durability-service qos policy values. @@ -833,17 +761,10 @@ void dds_qget_reader_data_lifecycle * @param[in,out] max_samples - Pointer that will store number of samples resource-limit policy applied by the durability service (optional) * @param[in,out] max_instances - Pointer that will store number of instances resource-limit policy applied by the durability service (optional) * @param[in,out] max_samples_per_instance - Pointer that will store number of samples per instance resource-limit policy applied by the durability service (optional) + * + * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object */ -DDS_EXPORT void dds_qget_durability_service -( - _In_ const dds_qos_t * qos, - _Out_opt_ dds_duration_t * service_cleanup_delay, - _Out_opt_ dds_history_kind_t * history_kind, - _Out_opt_ int32_t * history_depth, - _Out_opt_ int32_t * max_samples, - _Out_opt_ int32_t * max_instances, - _Out_opt_ int32_t * max_samples_per_instance -); +DDS_EXPORT bool dds_qget_durability_service (const dds_qos_t * __restrict qos, dds_duration_t *service_cleanup_delay, dds_history_kind_t *history_kind, int32_t *history_depth, int32_t *max_samples, int32_t *max_instances, int32_t *max_samples_per_instance); #if defined (__cplusplus) } diff --git a/src/core/ddsc/src/dds__builtin.h b/src/core/ddsc/src/dds__builtin.h index 284f968..3601d67 100644 --- a/src/core/ddsc/src/dds__builtin.h +++ b/src/core/ddsc/src/dds__builtin.h @@ -13,7 +13,7 @@ #define _DDS_BUILTIN_H_ #include "ddsi/q_time.h" -#include "dds_builtinTopics.h" +#include "ddsi/ddsi_serdata_builtin.h" #if defined (__cplusplus) @@ -22,7 +22,6 @@ extern "C" #endif - /* Get actual topic in related participant related to topic 'id'. */ _Must_inspect_result_ dds_entity_t dds__get_builtin_topic( @@ -39,7 +38,8 @@ _Must_inspect_result_ dds_entity_t dds__get_builtin_subscriber( _In_ dds_entity_t e); - +/* Checks whether the reader QoS is valid for use with built-in topic TOPIC */ +bool dds__validate_builtin_reader_qos(dds_entity_t topic, const dds_qos_t *qos); /* Initialization and finalize functions. */ void @@ -50,19 +50,12 @@ void dds__builtin_fini( void); - - -/* Callback functions that contain received builtin data. */ void -dds__builtin_participant_cb( - DDS_ParticipantBuiltinTopicData *data, - nn_wctime_t timestamp); - -void -dds__builtin_cmparticipant_cb( - DDS_CMParticipantBuiltinTopicData *data, - nn_wctime_t timestamp); - +dds__builtin_write( + _In_ enum ddsi_sertopic_builtin_type type, + _In_ const nn_guid_t *guid, + _In_ nn_wctime_t timestamp, + _In_ bool alive); #if defined (__cplusplus) } diff --git a/src/core/ddsc/src/dds_alloc.c b/src/core/ddsc/src/dds_alloc.c index 049d9aa..3c5546d 100644 --- a/src/core/ddsc/src/dds_alloc.c +++ b/src/core/ddsc/src/dds_alloc.c @@ -76,8 +76,9 @@ char * dds_string_dup (const char * str) char * ret = NULL; if (str) { - ret = dds_alloc (strlen (str) + 1); - strcpy (ret, str); + size_t sz = strlen (str) + 1; + ret = dds_alloc (sz); + memcpy (ret, str, sz); } return ret; } diff --git a/src/core/ddsc/src/dds_builtin.c b/src/core/ddsc/src/dds_builtin.c index a93dabc..920e3f1 100644 --- a/src/core/ddsc/src/dds_builtin.c +++ b/src/core/ddsc/src/dds_builtin.c @@ -14,7 +14,6 @@ #include "ddsi/q_entity.h" #include "ddsi/q_thread.h" #include "ddsi/q_config.h" -#include "ddsi/q_builtin_topic.h" #include "dds__init.h" #include "dds__qos.h" #include "dds__domain.h" @@ -23,7 +22,10 @@ #include "dds__types.h" #include "dds__builtin.h" #include "dds__subscriber.h" - +#include "dds__write.h" +#include "dds__writer.h" +#include "ddsi/q_qosmatch.h" +#include "ddsi/ddsi_serdata_builtin.h" static dds_return_t dds__delete_builtin_participant( @@ -37,7 +39,7 @@ static _Must_inspect_result_ dds_entity_t dds__create_builtin_publisher( _In_ dds_entity_t participant); -static _Must_inspect_result_ dds_entity_t +static dds_entity_t dds__create_builtin_writer( _In_ dds_entity_t topic); @@ -56,17 +58,23 @@ static dds_entity_t g_builtin_local_participant = 0; static dds_entity_t g_builtin_local_publisher = 0; static dds_entity_t g_builtin_local_writers[] = { 0, /* index DDS_BUILTIN_TOPIC_DCPSPARTICIPANT - DDS_KIND_INTERNAL - 1 */ - 0, /* index DDS_BUILTIN_TOPIC_CMPARTICIPANT - DDS_KIND_INTERNAL - 1 */ - 0, /* index DDS_BUILTIN_TOPIC_DCPSTYPE - DDS_KIND_INTERNAL - 1 */ 0, /* index DDS_BUILTIN_TOPIC_DCPSTOPIC - DDS_KIND_INTERNAL - 1 */ 0, /* index DDS_BUILTIN_TOPIC_DCPSPUBLICATION - DDS_KIND_INTERNAL - 1 */ - 0, /* index DDS_BUILTIN_TOPIC_CMPUBLISHER - DDS_KIND_INTERNAL - 1 */ 0, /* index DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION - DDS_KIND_INTERNAL - 1 */ - 0, /* index DDS_BUILTIN_TOPIC_CMSUBSCRIBER - DDS_KIND_INTERNAL - 1 */ - 0, /* index DDS_BUILTIN_TOPIC_CMDATAWRITER - DDS_KIND_INTERNAL - 1 */ - 0, /* index DDS_BUILTIN_TOPIC_CMDATAREADER - DDS_KIND_INTERNAL - 1 */ }; +static _Must_inspect_result_ dds_qos_t * +dds__create_builtin_qos( + void) +{ + const char *partition = "__BUILT-IN PARTITION__"; + dds_qos_t *qos = dds_create_qos(); + dds_qset_durability(qos, DDS_DURABILITY_TRANSIENT_LOCAL); + dds_qset_presentation(qos, DDS_PRESENTATION_TOPIC, false, false); + dds_qset_reliability(qos, DDS_RELIABILITY_RELIABLE, DDS_MSECS(100)); + dds_qset_partition(qos, 1, &partition); + return qos; +} static dds_return_t dds__delete_builtin_participant( @@ -148,17 +156,9 @@ static _Must_inspect_result_ dds_entity_t dds__create_builtin_publisher( _In_ dds_entity_t participant) { - dds_entity_t pub; - dds_qos_t *qos; - const char *partition = "__BUILT-IN PARTITION__"; - - qos = dds_create_qos(); - dds_qset_partition(qos, 1, &partition); - - pub = dds_create_publisher(participant, qos, NULL); - + dds_qos_t *qos = dds__create_builtin_qos(); + dds_entity_t pub = dds_create_publisher(participant, qos, NULL); dds_delete_qos(qos); - return pub; } @@ -166,21 +166,13 @@ static _Must_inspect_result_ dds_entity_t dds__create_builtin_subscriber( _In_ dds_entity *participant) { - dds_entity_t sub; - dds_qos_t *qos; - const char *partition = "__BUILT-IN PARTITION__"; - - qos = dds_create_qos(); - dds_qset_partition(qos, 1, &partition); - - /* Create builtin-subscriber */ - sub = dds__create_subscriber_l(participant, qos, NULL); + dds_qos_t *qos = dds__create_builtin_qos(); + dds_entity_t sub = dds__create_subscriber_l(participant, qos, NULL); dds_delete_qos(qos); - return sub; } -static _Must_inspect_result_ dds_entity_t +static dds_entity_t dds__create_builtin_writer( _In_ dds_entity_t topic) { @@ -189,13 +181,7 @@ dds__create_builtin_writer( if (pub > 0) { dds_entity_t top = dds__get_builtin_topic(pub, topic); if (top > 0) { - dds_qos_t *qos; - // TODO: set builtin qos - qos = dds_create_qos(); - dds_qset_durability(qos, DDS_DURABILITY_TRANSIENT_LOCAL); - dds_qset_reliability(qos, DDS_RELIABILITY_RELIABLE, DDS_MSECS(100)); - wr = dds_create_writer(pub, top, qos, NULL); - dds_delete_qos(qos); + wr = dds_create_writer(pub, top, NULL, NULL); (void)dds_delete(top); } else { wr = top; @@ -213,6 +199,9 @@ dds__get_builtin_participant( { if (g_builtin_local_participant == 0) { g_builtin_local_participant = dds__create_builtin_participant(); + (void)dds__create_builtin_writer(DDS_BUILTIN_TOPIC_DCPSPARTICIPANT); + (void)dds__create_builtin_writer(DDS_BUILTIN_TOPIC_DCPSPUBLICATION); + (void)dds__create_builtin_writer(DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION); } return g_builtin_local_participant; } @@ -277,57 +266,26 @@ dds__get_builtin_topic( participant = dds_get_participant(e); if (participant > 0) { - const dds_topic_descriptor_t *desc; - const char *name; + struct ddsi_sertopic *sertopic; if (topic == DDS_BUILTIN_TOPIC_DCPSPARTICIPANT) { - desc = &DDS_ParticipantBuiltinTopicData_desc; - name = "DCPSParticipant"; - } else if (topic == DDS_BUILTIN_TOPIC_CMPARTICIPANT) { - desc = &DDS_CMParticipantBuiltinTopicData_desc; - name = "CMParticipant"; - } else if (topic == DDS_BUILTIN_TOPIC_DCPSTYPE) { - desc = &DDS_TypeBuiltinTopicData_desc; - name = "DCPSType"; - } else if (topic == DDS_BUILTIN_TOPIC_DCPSTOPIC) { - desc = &DDS_TopicBuiltinTopicData_desc; - name = "DCPSTopic"; + sertopic = gv.builtin_participant_topic; } else if (topic == DDS_BUILTIN_TOPIC_DCPSPUBLICATION) { - desc = &DDS_PublicationBuiltinTopicData_desc; - name = "DCPSPublication"; - } else if (topic == DDS_BUILTIN_TOPIC_CMPUBLISHER) { - desc = &DDS_CMPublisherBuiltinTopicData_desc; - name = "CMPublisher"; + sertopic = gv.builtin_writer_topic; } else if (topic == DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION) { - desc = &DDS_SubscriptionBuiltinTopicData_desc; - name = "DCPSSubscription"; - } else if (topic == DDS_BUILTIN_TOPIC_CMSUBSCRIBER) { - desc = &DDS_CMSubscriberBuiltinTopicData_desc; - name = "CMSubscriber"; - } else if (topic == DDS_BUILTIN_TOPIC_CMDATAWRITER) { - desc = &DDS_CMDataWriterBuiltinTopicData_desc; - name = "CMDataWriter"; - } else if (topic == DDS_BUILTIN_TOPIC_CMDATAREADER) { - desc = &DDS_CMDataReaderBuiltinTopicData_desc; - name = "CMDataReader"; + sertopic = gv.builtin_reader_topic; } else { DDS_ERROR("Invalid builtin-topic handle(%d)\n", topic); ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER); goto err_invalid_topic; } - ret = dds_find_topic(participant, name); + ret = dds_find_topic (participant, sertopic->name); if (ret < 0 && dds_err_nr(ret) == DDS_RETCODE_PRECONDITION_NOT_MET) { - dds_qos_t *tqos; - - tqos = dds_create_qos(); - dds_qset_durability(tqos, DDS_DURABILITY_TRANSIENT_LOCAL); - dds_qset_presentation(tqos, DDS_PRESENTATION_TOPIC, false, false); - dds_qset_reliability(tqos, DDS_RELIABILITY_RELIABLE, DDS_MSECS(100)); - ret = dds_create_topic(participant, desc, name, tqos, NULL); - dds_delete_qos(tqos); + dds_qos_t *qos = dds__create_builtin_qos(); + ret = dds_create_topic_arbitrary(participant, sertopic, sertopic->name, qos, NULL, NULL); + dds_delete_qos(qos); } - } else { /* Failed to get participant of provided entity */ ret = participant; @@ -343,7 +301,7 @@ dds__get_builtin_writer( _In_ dds_entity_t topic) { dds_entity_t wr; - if ((topic >= DDS_BUILTIN_TOPIC_DCPSPARTICIPANT) && (topic <= DDS_BUILTIN_TOPIC_CMDATAREADER)) { + if ((topic >= DDS_BUILTIN_TOPIC_DCPSPARTICIPANT) && (topic <= DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION)) { int index = (int)(topic - DDS_KIND_INTERNAL - 1); os_mutexLock(&g_builtin_mutex); wr = g_builtin_local_writers[index]; @@ -362,21 +320,40 @@ dds__get_builtin_writer( } static dds_return_t -dds__builtin_write( - _In_ dds_entity_t topic, - _In_ const void *data, - _In_ dds_time_t timestamp, - _In_ int alive) +dds__builtin_write_int( + _In_ dds_entity_t topic, + _In_ const nn_guid_t *guid, + _In_ dds_time_t timestamp, + _In_ bool alive) { dds_return_t ret = DDS_RETCODE_OK; if (os_atomic_inc32_nv(&m_call_count) > 1) { dds_entity_t wr; wr = dds__get_builtin_writer(topic); if (wr > 0) { - if (alive) { - ret = dds_write_ts(wr, data, timestamp); + struct ddsi_sertopic *sertopic; + struct ddsi_serdata *serdata; + struct nn_keyhash keyhash; + struct dds_writer *wraddr; + + if (topic == DDS_BUILTIN_TOPIC_DCPSPARTICIPANT) { + sertopic = gv.builtin_participant_topic; + } else if (topic == DDS_BUILTIN_TOPIC_DCPSPUBLICATION) { + sertopic = gv.builtin_writer_topic; + } else if (topic == DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION) { + sertopic = gv.builtin_reader_topic; } else { - ret = dds_dispose_ts(wr, data, timestamp); + sertopic = NULL; + assert (0); + } + + memcpy (&keyhash, guid, sizeof (keyhash)); + serdata = ddsi_serdata_from_keyhash(sertopic, &keyhash); + + ret = dds_writer_lock(wr, &wraddr); + if (ret == DDS_RETCODE_OK) { + ret = dds_writecdr_impl (wraddr, serdata, timestamp, alive ? 0 : (DDS_WR_DISPOSE_BIT | DDS_WR_UNREGISTER_BIT)); + dds_writer_unlock(wraddr); } } else { ret = wr; @@ -386,6 +363,56 @@ dds__builtin_write( return ret; } +void +dds__builtin_write( + _In_ enum ddsi_sertopic_builtin_type type, + _In_ const nn_guid_t *guid, + _In_ nn_wctime_t timestamp, + _In_ bool alive) +{ + dds_entity_t topic; + switch (type) + { + case DSBT_PARTICIPANT: + topic = DDS_BUILTIN_TOPIC_DCPSPARTICIPANT; + break; + case DSBT_WRITER: + topic = DDS_BUILTIN_TOPIC_DCPSPUBLICATION; + break; + case DSBT_READER: + topic = DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION; + break; + } + (void)dds__builtin_write_int(topic, guid, timestamp.v, alive); +} + +bool dds__validate_builtin_reader_qos(dds_entity_t topic, const dds_qos_t *qos) +{ + if (qos == NULL) { + /* default QoS inherited from topic is ok by definition */ + return true; + } else { + dds_entity_t wr = dds__get_builtin_writer(topic); + dds_qos_t *wrqos = dds_create_qos(); + dds_return_t ret = dds_get_qos(wr, wrqos); + bool match; + assert (ret == DDS_RETCODE_OK); + (void)ret; + if (!qos_match_p (qos, wrqos)) { + match = false; + } else if (qos->resource_limits.max_samples != DDS_LENGTH_UNLIMITED || + qos->resource_limits.max_instances != DDS_LENGTH_UNLIMITED || + qos->resource_limits.max_samples_per_instance != DDS_LENGTH_UNLIMITED) { + /* this means a write on the built-in topic writer can't fail */ + match = false; + } else { + match = true; + } + dds_delete_qos(wrqos); + return match; + } +} + void dds__builtin_init( void) @@ -410,22 +437,3 @@ dds__builtin_fini( memset(g_builtin_local_writers, 0, sizeof(g_builtin_local_writers)); os_mutexDestroy(&g_builtin_mutex); } - - -void -forward_builtin_participant( - _In_ DDS_ParticipantBuiltinTopicData *data, - _In_ nn_wctime_t timestamp, - _In_ int alive) -{ - dds__builtin_write(DDS_BUILTIN_TOPIC_DCPSPARTICIPANT, data, timestamp.v, alive); -} - -void -forward_builtin_cmparticipant( - _In_ DDS_CMParticipantBuiltinTopicData *data, - _In_ nn_wctime_t timestamp, - _In_ int alive) -{ - dds__builtin_write(DDS_BUILTIN_TOPIC_CMPARTICIPANT, data, timestamp.v, alive); -} diff --git a/src/core/ddsc/src/dds_builtinTopics.idl b/src/core/ddsc/src/dds_builtinTopics.idl deleted file mode 100644 index 1819849..0000000 --- a/src/core/ddsc/src/dds_builtinTopics.idl +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License - * v. 1.0 which is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause - */ -#ifndef OSPL_DDS_BUILTINTOPICS_IDL -#define OSPL_DDS_BUILTINTOPICS_IDL - -/* -This file was the one orginally in ./src/api/dcps/saj/code/. -(and therefore by implication ./src/api/dcps/cj/java/code). -*/ - -#define BUILTIN_TOPIC_KEY_TYPE_NATIVE unsigned long - -module DDS { - - - // Added octet sequence definition. - // Prevents IDL compiler warnings from deprecated anonymous types - // on composite type members. - typedef sequence octSeq; - - typedef BUILTIN_TOPIC_KEY_TYPE_NATIVE BuiltinTopicKey_t[3]; - typedef sequence StringSeq; - typedef short DataRepresentationId_t; - - const DataRepresentationId_t XCDR_REPRESENTATION = 0; - const DataRepresentationId_t XML_REPRESENTATION = 0x001; - const DataRepresentationId_t OSPL_REPRESENTATION = 0x400; - const DataRepresentationId_t GPB_REPRESENTATION = 0x401; - const DataRepresentationId_t INVALID_REPRESENTATION = 0x7FFF; - - struct Duration_t { - long sec; - unsigned long nanosec; - }; - - struct UserDataQosPolicy { - octSeq value; - // replaced deprecated anonymous sequence value; - }; - - struct TopicDataQosPolicy { - octSeq value; - // replaced deprecated anonymous sequence value; - }; - - struct GroupDataQosPolicy { - octSeq value; - // replaced deprected anonymous sequence value; - }; - - struct TransportPriorityQosPolicy { - long value; - }; - - struct LifespanQosPolicy { - Duration_t duration; - }; - - enum DurabilityQosPolicyKind { - VOLATILE_DURABILITY_QOS, - TRANSIENT_LOCAL_DURABILITY_QOS, - TRANSIENT_DURABILITY_QOS, - PERSISTENT_DURABILITY_QOS - }; - - struct DurabilityQosPolicy { - DurabilityQosPolicyKind kind; - }; - - enum PresentationQosPolicyAccessScopeKind { - INSTANCE_PRESENTATION_QOS, - TOPIC_PRESENTATION_QOS, - GROUP_PRESENTATION_QOS - }; - - struct PresentationQosPolicy { - PresentationQosPolicyAccessScopeKind access_scope; - boolean coherent_access; - boolean ordered_access; - }; - - struct DeadlineQosPolicy { - Duration_t period; - }; - - struct LatencyBudgetQosPolicy { - Duration_t duration; - }; - - enum OwnershipQosPolicyKind { - SHARED_OWNERSHIP_QOS, - EXCLUSIVE_OWNERSHIP_QOS - }; - - struct OwnershipQosPolicy { - OwnershipQosPolicyKind kind; - }; - - struct OwnershipStrengthQosPolicy { - long value; - }; - - enum LivelinessQosPolicyKind { - AUTOMATIC_LIVELINESS_QOS, - MANUAL_BY_PARTICIPANT_LIVELINESS_QOS, - MANUAL_BY_TOPIC_LIVELINESS_QOS - }; - - struct LivelinessQosPolicy { - LivelinessQosPolicyKind kind; - Duration_t lease_duration; - }; - - struct TimeBasedFilterQosPolicy { - Duration_t minimum_separation; - }; - - struct PartitionQosPolicy { - StringSeq name; - }; - - enum ReliabilityQosPolicyKind { - BEST_EFFORT_RELIABILITY_QOS, - RELIABLE_RELIABILITY_QOS - }; - - struct ReliabilityQosPolicy { - ReliabilityQosPolicyKind kind; - Duration_t max_blocking_time; - boolean synchronous; - }; - - enum DestinationOrderQosPolicyKind { - BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS, - BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS - }; - - struct DestinationOrderQosPolicy { - DestinationOrderQosPolicyKind kind; - }; - - enum HistoryQosPolicyKind { - KEEP_LAST_HISTORY_QOS, - KEEP_ALL_HISTORY_QOS - }; - - struct HistoryQosPolicy { - HistoryQosPolicyKind kind; - long depth; - }; - - struct ResourceLimitsQosPolicy { - long max_samples; - long max_instances; - long max_samples_per_instance; - }; - - struct DurabilityServiceQosPolicy { - Duration_t service_cleanup_delay; - HistoryQosPolicyKind history_kind; - long history_depth; - long max_samples; - long max_instances; - long max_samples_per_instance; - }; - - struct ProductDataQosPolicy { - string value; - }; - - struct EntityFactoryQosPolicy { - boolean autoenable_created_entities; - }; - - struct ShareQosPolicy { - string name; - boolean enable; - }; - - struct WriterDataLifecycleQosPolicy { - boolean autodispose_unregistered_instances; - Duration_t autopurge_suspended_samples_delay; - Duration_t autounregister_instance_delay; - }; - - enum InvalidSampleVisibilityQosPolicyKind { - NO_INVALID_SAMPLES, - MINIMUM_INVALID_SAMPLES, - ALL_INVALID_SAMPLES - }; - - struct InvalidSampleVisibilityQosPolicy { - InvalidSampleVisibilityQosPolicyKind kind; - }; - -// @discrepancy The below QoS did not exist in ./etc/idlpp/dds_dcps.idl Retain ? - - struct SubscriptionKeyQosPolicy { - boolean use_key_list; - StringSeq key_list; - }; - -// @discrepancy End of above discrepancy - - struct ReaderDataLifecycleQosPolicy { - Duration_t autopurge_nowriter_samples_delay; - Duration_t autopurge_disposed_samples_delay; - boolean autopurge_dispose_all; - // @discrepancy The below member existed in this file but did not - // in ./etc/idlpp/dds_dcps.idl. Retain ? - boolean enable_invalid_samples; // @deprecated Will be replaced by invalid_sample_visibility in due time - InvalidSampleVisibilityQosPolicy invalid_sample_visibility; - }; - - struct UserKeyQosPolicy { - boolean enable; - string expression; - }; - - struct ReaderLifespanQosPolicy { - boolean use_lifespan; - Duration_t duration; - }; - - struct TypeHash { - unsigned long long msb; - unsigned long long lsb; - }; - - struct ParticipantBuiltinTopicData { - BuiltinTopicKey_t key; - UserDataQosPolicy user_data; - }; -#pragma keylist ParticipantBuiltinTopicData key - - struct TopicBuiltinTopicData { - BuiltinTopicKey_t key; - string name; - string type_name; - DurabilityQosPolicy durability; - DurabilityServiceQosPolicy durability_service; - DeadlineQosPolicy deadline; - LatencyBudgetQosPolicy latency_budget; - LivelinessQosPolicy liveliness; - ReliabilityQosPolicy reliability; - TransportPriorityQosPolicy transport_priority; - LifespanQosPolicy lifespan; - DestinationOrderQosPolicy destination_order; - HistoryQosPolicy history; - ResourceLimitsQosPolicy resource_limits; - OwnershipQosPolicy ownership; - TopicDataQosPolicy topic_data; - }; -#pragma keylist TopicBuiltinTopicData key - - struct TypeBuiltinTopicData { - string name; - DataRepresentationId_t data_representation_id; - TypeHash type_hash; - octSeq meta_data; - octSeq extentions; - }; -#pragma keylist TypeBuiltinTopicData name data_representation_id type_hash.msb type_hash.lsb - - struct PublicationBuiltinTopicData { - BuiltinTopicKey_t key; - BuiltinTopicKey_t participant_key; - string topic_name; - string type_name; - DurabilityQosPolicy durability; - DeadlineQosPolicy deadline; - LatencyBudgetQosPolicy latency_budget; - LivelinessQosPolicy liveliness; - ReliabilityQosPolicy reliability; - LifespanQosPolicy lifespan; - DestinationOrderQosPolicy destination_order; - UserDataQosPolicy user_data; - OwnershipQosPolicy ownership; - OwnershipStrengthQosPolicy ownership_strength; - PresentationQosPolicy presentation; - PartitionQosPolicy partition; - TopicDataQosPolicy topic_data; - GroupDataQosPolicy group_data; - }; -#pragma keylist PublicationBuiltinTopicData key - - struct SubscriptionBuiltinTopicData { - BuiltinTopicKey_t key; - BuiltinTopicKey_t participant_key; - string topic_name; - string type_name; - DurabilityQosPolicy durability; - DeadlineQosPolicy deadline; - LatencyBudgetQosPolicy latency_budget; - LivelinessQosPolicy liveliness; - ReliabilityQosPolicy reliability; - OwnershipQosPolicy ownership; - DestinationOrderQosPolicy destination_order; - UserDataQosPolicy user_data; - TimeBasedFilterQosPolicy time_based_filter; - PresentationQosPolicy presentation; - PartitionQosPolicy partition; - TopicDataQosPolicy topic_data; - GroupDataQosPolicy group_data; - }; -#pragma keylist SubscriptionBuiltinTopicData key - - struct CMParticipantBuiltinTopicData { - BuiltinTopicKey_t key; - ProductDataQosPolicy product; - }; -#pragma keylist CMParticipantBuiltinTopicData key - - struct CMPublisherBuiltinTopicData { - BuiltinTopicKey_t key; - ProductDataQosPolicy product; - BuiltinTopicKey_t participant_key; - string name; - EntityFactoryQosPolicy entity_factory; - PartitionQosPolicy partition; - }; -#pragma keylist CMPublisherBuiltinTopicData key - - struct CMSubscriberBuiltinTopicData { - BuiltinTopicKey_t key; - ProductDataQosPolicy product; - BuiltinTopicKey_t participant_key; - string name; - EntityFactoryQosPolicy entity_factory; - ShareQosPolicy share; - PartitionQosPolicy partition; - }; -#pragma keylist CMSubscriberBuiltinTopicData key - - struct CMDataWriterBuiltinTopicData { - BuiltinTopicKey_t key; - ProductDataQosPolicy product; - BuiltinTopicKey_t publisher_key; - string name; - HistoryQosPolicy history; - ResourceLimitsQosPolicy resource_limits; - WriterDataLifecycleQosPolicy writer_data_lifecycle; - }; -#pragma keylist CMDataWriterBuiltinTopicData key - - struct CMDataReaderBuiltinTopicData { - BuiltinTopicKey_t key; - ProductDataQosPolicy product; - BuiltinTopicKey_t subscriber_key; - string name; - HistoryQosPolicy history; - ResourceLimitsQosPolicy resource_limits; - ReaderDataLifecycleQosPolicy reader_data_lifecycle; - UserKeyQosPolicy subscription_keys; - ReaderLifespanQosPolicy reader_lifespan; - ShareQosPolicy share; - }; -#pragma keylist CMDataReaderBuiltinTopicData key - -}; - -#endif /* OSPL_DDS_BUILTINTOPICS_IDL */ diff --git a/src/core/ddsc/src/dds_dcps_builtintopics.idl b/src/core/ddsc/src/dds_dcps_builtintopics.idl deleted file mode 100644 index cfa394a..0000000 --- a/src/core/ddsc/src/dds_dcps_builtintopics.idl +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License - * v. 1.0 which is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause - */ -#ifndef OSPL_DDS_DCPS_BUILTINTOPICS_IDL -#define OSPL_DDS_DCPS_BUILTINTOPICS_IDL - -/** -*This file (name) was orginally in ./src/api/dcps/ccpp/idl/. -*It's been modified to include from another file the base definitions -*required for this 'built in topics' superset... : -*/ - -#include "dds_builtinTopics.idl" - -module DDS { - - struct Time_t { - long sec; - unsigned long nanosec; - }; - - enum SchedulingClassQosPolicyKind { - SCHEDULE_DEFAULT, - SCHEDULE_TIMESHARING, - SCHEDULE_REALTIME - }; - - struct SchedulingClassQosPolicy { - SchedulingClassQosPolicyKind kind; - }; - - enum SchedulingPriorityQosPolicyKind { - PRIORITY_RELATIVE, - PRIORITY_ABSOLUTE - }; - - struct SchedulingPriorityQosPolicy { - SchedulingPriorityQosPolicyKind kind; - }; - - struct SchedulingQosPolicy { - SchedulingClassQosPolicy scheduling_class; - SchedulingPriorityQosPolicy scheduling_priority_kind; - long scheduling_priority; - }; - - struct DomainParticipantQos { - UserDataQosPolicy user_data; - EntityFactoryQosPolicy entity_factory; - SchedulingQosPolicy watchdog_scheduling; - SchedulingQosPolicy listener_scheduling; - }; - - struct TopicQos { - TopicDataQosPolicy topic_data; - DurabilityQosPolicy durability; - DurabilityServiceQosPolicy durability_service; - DeadlineQosPolicy deadline; - LatencyBudgetQosPolicy latency_budget; - LivelinessQosPolicy liveliness; - ReliabilityQosPolicy reliability; - DestinationOrderQosPolicy destination_order; - HistoryQosPolicy history; - ResourceLimitsQosPolicy resource_limits; - TransportPriorityQosPolicy transport_priority; - LifespanQosPolicy lifespan; - OwnershipQosPolicy ownership; - }; - - struct DataWriterQos { - DurabilityQosPolicy durability; - DeadlineQosPolicy deadline; - LatencyBudgetQosPolicy latency_budget; - LivelinessQosPolicy liveliness; - ReliabilityQosPolicy reliability; - DestinationOrderQosPolicy destination_order; - HistoryQosPolicy history; - ResourceLimitsQosPolicy resource_limits; - TransportPriorityQosPolicy transport_priority; - LifespanQosPolicy lifespan; - UserDataQosPolicy user_data; - OwnershipQosPolicy ownership; - OwnershipStrengthQosPolicy ownership_strength; - WriterDataLifecycleQosPolicy writer_data_lifecycle; - }; - - struct PublisherQos { - PresentationQosPolicy presentation; - PartitionQosPolicy partition; - GroupDataQosPolicy group_data; - EntityFactoryQosPolicy entity_factory; - }; - - struct DataReaderQos { - DurabilityQosPolicy durability; - DeadlineQosPolicy deadline; - LatencyBudgetQosPolicy latency_budget; - LivelinessQosPolicy liveliness; - ReliabilityQosPolicy reliability; - DestinationOrderQosPolicy destination_order; - HistoryQosPolicy history; - ResourceLimitsQosPolicy resource_limits; - UserDataQosPolicy user_data; - OwnershipQosPolicy ownership; - TimeBasedFilterQosPolicy time_based_filter; - ReaderDataLifecycleQosPolicy reader_data_lifecycle; - SubscriptionKeyQosPolicy subscription_keys; - ReaderLifespanQosPolicy reader_lifespan; - ShareQosPolicy share; - }; - - struct SubscriberQos { - PresentationQosPolicy presentation; - PartitionQosPolicy partition; - GroupDataQosPolicy group_data; - EntityFactoryQosPolicy entity_factory; - ShareQosPolicy share; - }; - -}; - -#endif /* DDS_DCPS_BUILTINTOPICS_IDL */ diff --git a/src/core/ddsc/src/dds_init.c b/src/core/ddsc/src/dds_init.c index 19d11fc..cc224c4 100644 --- a/src/core/ddsc/src/dds_init.c +++ b/src/core/ddsc/src/dds_init.c @@ -250,12 +250,10 @@ static void dds__fini_plugin (void) void ddsi_plugin_init (void) { - /* Register initialization/clean functions */ - ddsi_plugin.init_fn = dds__init_plugin; ddsi_plugin.fini_fn = dds__fini_plugin; - /* Register read cache functions */ + ddsi_plugin.builtin_write = dds__builtin_write; ddsi_plugin.rhc_plugin.rhc_free_fn = dds_rhc_free; ddsi_plugin.rhc_plugin.rhc_fini_fn = dds_rhc_fini; diff --git a/src/core/ddsc/src/dds_qos.c b/src/core/ddsc/src/dds_qos.c index 30965f1..0e169fa 100644 --- a/src/core/ddsc/src/dds_qos.c +++ b/src/core/ddsc/src/dds_qos.c @@ -37,7 +37,7 @@ dds_qos_data_copy_in( } } -static void +static bool dds_qos_data_copy_out( _In_ const nn_octetseq_t * data, _When_(*sz == 0, _At_(*value, _Post_null_)) @@ -45,13 +45,22 @@ dds_qos_data_copy_out( _Outptr_result_bytebuffer_all_maybenull_(*sz) void ** value, _Out_ size_t * sz) { - if ((*sz = data->length) != 0) { - assert(data->value); - *value = dds_alloc(data->length); - memcpy(*value, data->value, data->length); - } else { - *value = NULL; + if (sz == NULL && value != NULL) { + return false; } + if (sz) { + *sz = data->length; + } + if (value) { + if (data->length != 0) { + assert(data->value); + *value = dds_alloc(data->length); + memcpy(*value, data->value, data->length); + } else { + *value = NULL; + } + } + return true; } bool @@ -657,397 +666,276 @@ void dds_qset_durability_service } } -void dds_qget_userdata -( - _In_ const dds_qos_t * __restrict qos, - _Outptr_result_bytebuffer_maybenull_(*sz) void ** value, - _Out_ size_t * sz -) +bool dds_qget_userdata (const dds_qos_t * __restrict qos, void **value, size_t *sz) { - if(!qos) { - DDS_ERROR("Argument QoS is NULL\n"); - return ; + if (!qos || !(qos->present & QP_USER_DATA)) { + return false; } - if(!value) { - DDS_ERROR("Argument value is NULL\n"); - return ; - } - if(!sz) { - DDS_ERROR("Argument sz is NULL\n"); - return ; - } - dds_qos_data_copy_out (&qos->user_data, value, sz); + return dds_qos_data_copy_out (&qos->user_data, value, sz); } -void dds_qget_topicdata -( - _In_ const dds_qos_t * __restrict qos, - _Outptr_result_bytebuffer_maybenull_(*sz) void ** value, - _Out_ size_t * sz -) +bool dds_qget_topicdata (const dds_qos_t * __restrict qos, void **value, size_t *sz) { - if(!qos) { - DDS_ERROR("Argument QoS is NULL\n"); - return ; + if (!qos || !(qos->present & QP_TOPIC_DATA)) { + return false; } - if(!value) { - DDS_ERROR("Argument value is NULL\n"); - return ; - } - if(!sz) { - DDS_ERROR("Argument sz is NULL\n"); - return ; - } - dds_qos_data_copy_out (&qos->topic_data, value, sz); + return dds_qos_data_copy_out (&qos->topic_data, value, sz); } -void dds_qget_groupdata -( - _In_ const dds_qos_t * __restrict qos, - _Outptr_result_bytebuffer_maybenull_(*sz) void ** value, - _Out_ size_t * sz -) +bool dds_qget_groupdata (const dds_qos_t * __restrict qos, void **value, size_t *sz) { - if(!qos) { - DDS_ERROR("Argument QoS is NULL\n"); - return ; + if (!qos || !(qos->present & QP_GROUP_DATA)) { + return false; } - if(!value) { - DDS_ERROR("Argument value is NULL\n"); - return ; - } - if(!sz) { - DDS_ERROR("Argument sz is NULL\n"); - return ; - } - dds_qos_data_copy_out (&qos->group_data, value, sz); + return dds_qos_data_copy_out (&qos->group_data, value, sz); } -void dds_qget_durability -( - _In_ const dds_qos_t * __restrict qos, - _Out_ dds_durability_kind_t *kind -) +bool dds_qget_durability (const dds_qos_t * __restrict qos, dds_durability_kind_t *kind) { - if(!qos) { - DDS_ERROR("Argument QoS is NULL\n"); - return ; + if (!qos || !(qos->present & QP_DURABILITY)) { + return false; } - if(!kind) { - DDS_ERROR("Argument kind is NULL\n"); - return ; + if (kind) { + *kind = (dds_durability_kind_t) qos->durability.kind; } - *kind = (dds_durability_kind_t) qos->durability.kind; + return true; } -void dds_qget_history -( - _In_ const dds_qos_t * __restrict qos, - _Out_opt_ dds_history_kind_t * kind, - _Out_opt_ int32_t *depth -) +bool dds_qget_history (const dds_qos_t * __restrict qos, dds_history_kind_t *kind, int32_t *depth) { - if (qos) { - if (kind) *kind = (dds_history_kind_t) qos->history.kind; - if (depth) *depth = qos->history.depth; - } else { - DDS_ERROR("Argument qos is NULL\n"); + if (!qos || !(qos->present & QP_HISTORY)) { + return false; } + if (kind) { + *kind = (dds_history_kind_t) qos->history.kind; + } + if (depth) { + *depth = qos->history.depth; + } + return true; } -void dds_qget_resource_limits -( - _In_ const dds_qos_t * __restrict qos, - _Out_opt_ int32_t *max_samples, - _Out_opt_ int32_t *max_instances, - _Out_opt_ int32_t *max_samples_per_instance -) +bool dds_qget_resource_limits (const dds_qos_t * __restrict qos, int32_t *max_samples, int32_t *max_instances, int32_t *max_samples_per_instance) { - if (qos) { - if (max_samples) *max_samples = qos->resource_limits.max_samples; - if (max_instances) *max_instances = qos->resource_limits.max_instances; - if (max_samples_per_instance) { - *max_samples_per_instance = qos->resource_limits.max_samples_per_instance; - } - } else { - DDS_ERROR("Argument qos is NULL\n"); + if (!qos || !(qos->present & QP_RESOURCE_LIMITS)) { + return false; } + if (max_samples) { + *max_samples = qos->resource_limits.max_samples; + } + if (max_instances) { + *max_instances = qos->resource_limits.max_instances; + } + if (max_samples_per_instance) { + *max_samples_per_instance = qos->resource_limits.max_samples_per_instance; + } + return true; } -void dds_qget_presentation -( - _In_ const dds_qos_t * __restrict qos, - _Out_opt_ dds_presentation_access_scope_kind_t *access_scope, - _Out_opt_ bool *coherent_access, - _Out_opt_ bool *ordered_access -) +bool dds_qget_presentation (const dds_qos_t * __restrict qos, dds_presentation_access_scope_kind_t *access_scope, bool *coherent_access, bool *ordered_access) { - if (qos) { - if (access_scope) *access_scope = (dds_presentation_access_scope_kind_t) qos->presentation.access_scope; - if (coherent_access) *coherent_access = qos->presentation.coherent_access; - if (ordered_access) *ordered_access = qos->presentation.ordered_access; - } else { - DDS_ERROR("Argument qos is NULL\n"); + if (!qos || !(qos->present & QP_PRESENTATION)) { + return false; } + if (access_scope) { + *access_scope = (dds_presentation_access_scope_kind_t) qos->presentation.access_scope; + } + if (coherent_access) { + *coherent_access = qos->presentation.coherent_access; + } + if (ordered_access) { + *ordered_access = qos->presentation.ordered_access; + } + return true; } -void dds_qget_lifespan -( - _In_ const dds_qos_t * __restrict qos, - _Out_ dds_duration_t * lifespan -) +bool dds_qget_lifespan (const dds_qos_t * __restrict qos, dds_duration_t *lifespan) { - if(!qos){ - DDS_ERROR("Argument qos is NULL\n"); - return ; + if (!qos || !(qos->present & QP_LIFESPAN)) { + return false; } - if(!lifespan){ - DDS_ERROR("Argument lifespan is NULL\n"); - return ; + if (lifespan) { + *lifespan = nn_from_ddsi_duration (qos->lifespan.duration); } - *lifespan = nn_from_ddsi_duration (qos->lifespan.duration); + return true; } -void dds_qget_deadline -( - _In_ const dds_qos_t * __restrict qos, - _Out_ dds_duration_t * deadline -) +bool dds_qget_deadline (const dds_qos_t * __restrict qos, dds_duration_t *deadline) { - if(!qos){ - DDS_ERROR("Argument qos is NULL\n"); - return ; + if (!qos || !(qos->present & QP_DEADLINE)) { + return false; } - if(!deadline){ - DDS_ERROR("Argument deadline is NULL\n"); - return ; + if (deadline) { + *deadline = nn_from_ddsi_duration (qos->deadline.deadline); } - *deadline = nn_from_ddsi_duration (qos->deadline.deadline); + return true; } -void dds_qget_latency_budget -( - _In_ const dds_qos_t * __restrict qos, - _Out_ dds_duration_t *duration -) +bool dds_qget_latency_budget (const dds_qos_t * __restrict qos, dds_duration_t *duration) { - if(!qos){ - DDS_ERROR("Argument qos is NULL\n"); - return ; + if (!qos || !(qos->present & QP_LATENCY_BUDGET)) { + return false; } - if(!duration){ - DDS_ERROR("Argument duration is NULL\n"); - return ; + if (duration) { + *duration = nn_from_ddsi_duration (qos->latency_budget.duration); } - *duration = nn_from_ddsi_duration (qos->latency_budget.duration); + return true; } -void dds_qget_ownership -( - _In_ const dds_qos_t * __restrict qos, - _Out_ dds_ownership_kind_t *kind -) +bool dds_qget_ownership (const dds_qos_t * __restrict qos, dds_ownership_kind_t *kind) { - if(!qos){ - DDS_ERROR("Argument qos is NULL\n"); - return ; + if (!qos || !(qos->present & QP_OWNERSHIP)) { + return false; } - if(!kind){ - DDS_ERROR("Argument kind is NULL\n"); - return ; + if (kind) { + *kind = (dds_ownership_kind_t) qos->ownership.kind; } - *kind = (dds_ownership_kind_t) qos->ownership.kind; + return true; } -void dds_qget_ownership_strength -( - _In_ const dds_qos_t * __restrict qos, - _Out_ int32_t *value -) +bool dds_qget_ownership_strength (const dds_qos_t * __restrict qos, int32_t *value) { - if(!qos){ - DDS_ERROR("Argument qos is NULL\n"); - return ; + if (!qos || !(qos->present & QP_OWNERSHIP_STRENGTH)) { + return false; } - if(!value){ - DDS_ERROR("Argument value is NULL\n"); - return ; + if (value) { + *value = qos->ownership_strength.value; } - *value = qos->ownership_strength.value; + return true; } -void dds_qget_liveliness -( - _In_ const dds_qos_t * __restrict qos, - _Out_opt_ dds_liveliness_kind_t *kind, - _Out_opt_ dds_duration_t *lease_duration -) +bool dds_qget_liveliness (const dds_qos_t * __restrict qos, dds_liveliness_kind_t *kind, dds_duration_t *lease_duration) { - if (qos) { - if (kind) *kind = (dds_liveliness_kind_t) qos->liveliness.kind; - if (lease_duration) *lease_duration = nn_from_ddsi_duration (qos->liveliness.lease_duration); - } else { - DDS_ERROR("Argument qos is NULL\n"); + if (!qos || !(qos->present & QP_LIVELINESS)) { + return false; } + if (kind) { + *kind = (dds_liveliness_kind_t) qos->liveliness.kind; + } + if (lease_duration) { + *lease_duration = nn_from_ddsi_duration (qos->liveliness.lease_duration); + } + return true; } -void dds_qget_time_based_filter -( - _In_ const dds_qos_t * __restrict qos, - _Out_ dds_duration_t *minimum_separation -) +bool dds_qget_time_based_filter (const dds_qos_t * __restrict qos, dds_duration_t *minimum_separation) { - if(!qos){ - DDS_ERROR("Argument qos is NULL\n"); - return ; + if (!qos || !(qos->present & QP_TIME_BASED_FILTER)) { + return false; } - if(!minimum_separation){ - DDS_ERROR("Argument minimum_separation is NULL\n"); - return ; + if (minimum_separation) { + *minimum_separation = nn_from_ddsi_duration (qos->time_based_filter.minimum_separation); } - *minimum_separation = nn_from_ddsi_duration (qos->time_based_filter.minimum_separation); + return true; } -void dds_qget_partition -( - _In_ const dds_qos_t * __restrict qos, - _Out_ uint32_t *n, - _Outptr_opt_result_buffer_all_maybenull_(*n) char *** ps -) +bool dds_qget_partition (const dds_qos_t * __restrict qos, uint32_t *n, char ***ps) { - size_t len; - uint32_t i; - - if(!qos){ - DDS_ERROR("Argument qos is NULL\n"); - return ; + if (!qos || !(qos->present & QP_PARTITION)) { + return false; } - if(!n){ - DDS_ERROR("Argument n is NULL\n"); - return ; + if (n == NULL && ps != NULL) { + return false; } - - *n = qos->partition.n; - if ( ps ) { - if ( qos->partition.n != 0 ) { + if (n) { + *n = qos->partition.n; + } + if (ps) { + if (qos->partition.n != 0) { *ps = dds_alloc(sizeof(char*) * qos->partition.n); - for ( i = 0; i < qos->partition.n; i++ ) { - len = strlen(qos->partition.strs[i]) + 1; - (*ps)[i] = dds_alloc(len); - strncpy((*ps)[i], qos->partition.strs[i], len); + for (uint32_t i = 0; i < qos->partition.n; i++) { + (*ps)[i] = dds_string_dup(qos->partition.strs[i]); } } else { *ps = NULL; } } + return true; } -void dds_qget_reliability -( - _In_ const dds_qos_t * __restrict qos, - _Out_opt_ dds_reliability_kind_t *kind, - _Out_opt_ dds_duration_t *max_blocking_time -) +bool dds_qget_reliability (const dds_qos_t * __restrict qos, dds_reliability_kind_t *kind, dds_duration_t *max_blocking_time) { - if (qos) { - if (kind) *kind = (dds_reliability_kind_t) qos->reliability.kind; - if (max_blocking_time) *max_blocking_time = nn_from_ddsi_duration (qos->reliability.max_blocking_time); - } else { - DDS_ERROR("Argument qos is NULL\n"); + if (!qos || !(qos->present & QP_RELIABILITY)) { + return false; } + if (kind) { + *kind = (dds_reliability_kind_t) qos->reliability.kind; + } + if (max_blocking_time) { + *max_blocking_time = nn_from_ddsi_duration (qos->reliability.max_blocking_time); + } + return true; } -void dds_qget_transport_priority -( - _In_ const dds_qos_t * __restrict qos, - _Out_ int32_t *value -) +bool dds_qget_transport_priority (const dds_qos_t * __restrict qos, int32_t *value) { - if(!qos){ - DDS_ERROR("Argument qos is NULL\n"); - return ; + if (!qos || !(qos->present & QP_TRANSPORT_PRIORITY)) { + return false; } - if(!value){ - DDS_ERROR("Argument value is NULL\n"); - return ; + if (value) { + *value = qos->transport_priority.value; } - *value = qos->transport_priority.value; + return true; } -void dds_qget_destination_order -( - _In_ const dds_qos_t * __restrict qos, - _Out_ dds_destination_order_kind_t *kind -) +bool dds_qget_destination_order (const dds_qos_t * __restrict qos, dds_destination_order_kind_t *kind) { - if(!qos){ - DDS_ERROR("Argument qos is NULL\n"); - return ; + if (!qos || !(qos->present & QP_DESTINATION_ORDER)) { + return false; } - if(!kind){ - DDS_ERROR("Argument kind is NULL\n"); - return ; + if (kind) { + *kind = (dds_destination_order_kind_t) qos->destination_order.kind; } - *kind = (dds_destination_order_kind_t) qos->destination_order.kind; + return true; } -void dds_qget_writer_data_lifecycle -( - _In_ const dds_qos_t * __restrict qos, - _Out_ bool * autodispose -) +bool dds_qget_writer_data_lifecycle (const dds_qos_t * __restrict qos, bool *autodispose) { - if(!qos){ - DDS_ERROR("Argument qos is NULL\n"); - return ; + if (!qos || !(qos->present & QP_PRISMTECH_WRITER_DATA_LIFECYCLE)) { + return false; } - if(!autodispose){ - DDS_ERROR("Argument autodispose is NULL\n"); - return ; + if (autodispose) { + *autodispose = qos->writer_data_lifecycle.autodispose_unregistered_instances; } - *autodispose = qos->writer_data_lifecycle.autodispose_unregistered_instances; + return true; } -void dds_qget_reader_data_lifecycle -( - _In_ const dds_qos_t * __restrict qos, - _Out_opt_ dds_duration_t *autopurge_nowriter_samples_delay, - _Out_opt_ dds_duration_t *autopurge_disposed_samples_delay -) +bool dds_qget_reader_data_lifecycle (const dds_qos_t * __restrict qos, dds_duration_t *autopurge_nowriter_samples_delay, dds_duration_t *autopurge_disposed_samples_delay) { - if (qos) { - if (autopurge_nowriter_samples_delay) { - *autopurge_nowriter_samples_delay = \ - nn_from_ddsi_duration (qos->reader_data_lifecycle.autopurge_nowriter_samples_delay); - } - if (autopurge_disposed_samples_delay) { - *autopurge_disposed_samples_delay = \ - nn_from_ddsi_duration (qos->reader_data_lifecycle.autopurge_disposed_samples_delay); - } - } else { - DDS_ERROR("Argument qos is NULL\n"); + if (!qos || !(qos->present & QP_PRISMTECH_READER_DATA_LIFECYCLE)) { + return false; } + if (autopurge_nowriter_samples_delay) { + *autopurge_nowriter_samples_delay = nn_from_ddsi_duration (qos->reader_data_lifecycle.autopurge_nowriter_samples_delay); + } + if (autopurge_disposed_samples_delay) { + *autopurge_disposed_samples_delay = nn_from_ddsi_duration (qos->reader_data_lifecycle.autopurge_disposed_samples_delay); + } + return true; } -void dds_qget_durability_service -( - _In_ const dds_qos_t * qos, - _Out_opt_ dds_duration_t * service_cleanup_delay, - _Out_opt_ dds_history_kind_t * history_kind, - _Out_opt_ int32_t * history_depth, - _Out_opt_ int32_t * max_samples, - _Out_opt_ int32_t * max_instances, - _Out_opt_ int32_t * max_samples_per_instance -) +bool dds_qget_durability_service (const dds_qos_t * __restrict qos, dds_duration_t *service_cleanup_delay, dds_history_kind_t *history_kind, int32_t *history_depth, int32_t *max_samples, int32_t *max_instances, int32_t *max_samples_per_instance) { - if (qos) { - if (service_cleanup_delay) *service_cleanup_delay = nn_from_ddsi_duration (qos->durability_service.service_cleanup_delay); - if (history_kind) *history_kind = (dds_history_kind_t) qos->durability_service.history.kind; - if (history_depth) *history_depth = qos->durability_service.history.depth; - if (max_samples) *max_samples = qos->durability_service.resource_limits.max_samples; - if (max_instances) *max_instances = qos->durability_service.resource_limits.max_instances; - if (max_samples_per_instance) *max_samples_per_instance = qos->durability_service.resource_limits.max_samples_per_instance; - } else { - DDS_ERROR("Argument qos is NULL\n"); + if (!qos || !(qos->present & QP_DURABILITY_SERVICE)) { + return false; } + if (service_cleanup_delay) { + *service_cleanup_delay = nn_from_ddsi_duration (qos->durability_service.service_cleanup_delay); + } + if (history_kind) { + *history_kind = (dds_history_kind_t) qos->durability_service.history.kind; + } + if (history_depth) { + *history_depth = qos->durability_service.history.depth; + } + if (max_samples) { + *max_samples = qos->durability_service.resource_limits.max_samples; + } + if (max_instances) { + *max_instances = qos->durability_service.resource_limits.max_instances; + } + if (max_samples_per_instance) { + *max_samples_per_instance = qos->durability_service.resource_limits.max_samples_per_instance; + } + return true; } diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index 0c8e3e3..a54763f 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -22,6 +22,7 @@ #include "ddsi/q_entity.h" #include "ddsi/q_thread.h" #include "dds__builtin.h" +#include "ddsi/ddsi_sertopic.h" #include "ddsc/ddsc_project.h" #include "os/os.h" @@ -337,7 +338,6 @@ dds_reader_status_cb( } } - _Pre_satisfies_(((participant_or_subscriber & DDS_ENTITY_KIND_MASK) == DDS_KIND_SUBSCRIBER ) ||\ ((participant_or_subscriber & DDS_ENTITY_KIND_MASK) == DDS_KIND_PARTICIPANT) ) _Pre_satisfies_(((topic & DDS_ENTITY_KIND_MASK) == DDS_KIND_TOPIC ) ||\ @@ -371,7 +371,6 @@ dds_create_reader( } t = topic; } else { - /* TODO If qos is provided, we need to compare with writer qos to determine compatibility */ subscriber = dds__get_builtin_subscriber(participant_or_subscriber); t = dds__get_builtin_topic(subscriber, topic); } @@ -425,6 +424,14 @@ dds_create_reader( goto err_bad_qos; } + /* Additional checks required for built-in topics */ + if (dds_entity_kind(topic) == DDS_KIND_INTERNAL && !dds__validate_builtin_reader_qos(topic, qos)) { + dds_delete_qos(rqos); + DDS_ERROR("Invalid QoS specified for built-in topic reader"); + reader = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY); + goto err_bad_qos; + } + /* Create reader and associated read cache */ rd = dds_alloc (sizeof (*rd)); reader = dds_entity_init (&rd->m_entity, sub, DDS_KIND_READER, rqos, listener, DDS_READER_STATUS_MASK); @@ -482,6 +489,11 @@ err_tp_lock: (void)dds_delete(subscriber); } err_sub_lock: + if (dds_entity_kind(topic) == DDS_KIND_INTERNAL) { + /* If topic is builtin, then the topic entity is local and should + * be deleted because the application won't. */ + dds_delete(t); + } return reader; } diff --git a/src/core/ddsc/src/dds_rhc.c b/src/core/ddsc/src/dds_rhc.c index f30b5e4..012435f 100644 --- a/src/core/ddsc/src/dds_rhc.c +++ b/src/core/ddsc/src/dds_rhc.c @@ -1401,7 +1401,15 @@ void dds_rhc_unregister_wr time a new WR_IID will be used for the same writer, then we have all the time in the world to scan the cache & clean up and that we don't have to keep it locked all the time (even if we do it - that way now). */ + that way now). + + WR_IID was never reused while the built-in topics weren't getting + generated, but those really require the same instance id for the + same GUID if an instance still exists in some reader for that GUID. + So, if unregistration without locking the RHC is desired, entities + need to get two IIDs: the one visible to the application in the + built-in topics and in get_instance_handle, and one used internally + for tracking registrations and unregistrations. */ bool trigger_waitsets = false; struct rhc_instance *inst; struct ut_hhIter iter; diff --git a/src/core/ddsc/src/dds_topic.c b/src/core/ddsc/src/dds_topic.c index 0d85690..bd4774a 100644 --- a/src/core/ddsc/src/dds_topic.c +++ b/src/core/ddsc/src/dds_topic.c @@ -39,15 +39,9 @@ const ut_avlTreedef_t dds_topictree_def = UT_AVL_TREEDEF_INITIALIZER_INDKEY /* builtin-topic handles */ const dds_entity_t DDS_BUILTIN_TOPIC_DCPSPARTICIPANT = (DDS_KIND_INTERNAL + 1); -const dds_entity_t DDS_BUILTIN_TOPIC_CMPARTICIPANT = (DDS_KIND_INTERNAL + 2); -const dds_entity_t DDS_BUILTIN_TOPIC_DCPSTYPE = (DDS_KIND_INTERNAL + 3); -const dds_entity_t DDS_BUILTIN_TOPIC_DCPSTOPIC = (DDS_KIND_INTERNAL + 4); -const dds_entity_t DDS_BUILTIN_TOPIC_DCPSPUBLICATION = (DDS_KIND_INTERNAL + 5); -const dds_entity_t DDS_BUILTIN_TOPIC_CMPUBLISHER = (DDS_KIND_INTERNAL + 6); -const dds_entity_t DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION = (DDS_KIND_INTERNAL + 7); -const dds_entity_t DDS_BUILTIN_TOPIC_CMSUBSCRIBER = (DDS_KIND_INTERNAL + 8); -const dds_entity_t DDS_BUILTIN_TOPIC_CMDATAWRITER = (DDS_KIND_INTERNAL + 9); -const dds_entity_t DDS_BUILTIN_TOPIC_CMDATAREADER = (DDS_KIND_INTERNAL + 10); +const dds_entity_t DDS_BUILTIN_TOPIC_DCPSTOPIC = (DDS_KIND_INTERNAL + 2); +const dds_entity_t DDS_BUILTIN_TOPIC_DCPSPUBLICATION = (DDS_KIND_INTERNAL + 3); +const dds_entity_t DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION = (DDS_KIND_INTERNAL + 4); static bool is_valid_name( diff --git a/src/core/ddsc/tests/builtin_topics.c b/src/core/ddsc/tests/builtin_topics.c index e6b59bc..ff24221 100644 --- a/src/core/ddsc/tests/builtin_topics.c +++ b/src/core/ddsc/tests/builtin_topics.c @@ -14,133 +14,28 @@ #include "ddsc/dds.h" #include "os/os.h" #include "test-common.h" - #include "CUnit/Test.h" +#include "CUnit/Theory.h" static dds_entity_t g_participant = 0; static dds_entity_t g_subscriber = 0; static dds_entity_t g_publisher = 0; +static dds_entity_t g_writer = 0; +static dds_entity_t g_reader = 0; static dds_entity_t g_topic = 0; -#define MAX_SAMPLES 1 +#define MAX_SAMPLES 2 static dds_sample_info_t g_info[MAX_SAMPLES]; -static struct DDS_UserDataQosPolicy g_pol_userdata; -static struct DDS_TopicDataQosPolicy g_pol_topicdata; -static struct DDS_GroupDataQosPolicy g_pol_groupdata; -static struct DDS_DurabilityQosPolicy g_pol_durability; -static struct DDS_HistoryQosPolicy g_pol_history; -static struct DDS_ResourceLimitsQosPolicy g_pol_resource_limits; -static struct DDS_PresentationQosPolicy g_pol_presentation; -static struct DDS_LifespanQosPolicy g_pol_lifespan; -static struct DDS_DeadlineQosPolicy g_pol_deadline; -static struct DDS_LatencyBudgetQosPolicy g_pol_latency_budget; -static struct DDS_OwnershipQosPolicy g_pol_ownership; -static struct DDS_OwnershipStrengthQosPolicy g_pol_ownership_strength; -static struct DDS_LivelinessQosPolicy g_pol_liveliness; -static struct DDS_TimeBasedFilterQosPolicy g_pol_time_based_filter; -static struct DDS_PartitionQosPolicy g_pol_partition; -static struct DDS_ReliabilityQosPolicy g_pol_reliability; -static struct DDS_TransportPriorityQosPolicy g_pol_transport_priority; -static struct DDS_DestinationOrderQosPolicy g_pol_destination_order; -static struct DDS_WriterDataLifecycleQosPolicy g_pol_writer_data_lifecycle; -static struct DDS_ReaderDataLifecycleQosPolicy g_pol_reader_data_lifecycle; -static struct DDS_DurabilityServiceQosPolicy g_pol_durability_service; - -static const char* c_userdata = "user_key"; -static const char* c_topicdata = "topic_key"; -static const char* c_groupdata = "group_key"; -static const char* c_partitions[] = {"Partition1", "Partition2"}; - -static dds_qos_t *g_qos = NULL; - static void qos_init(void) { - g_qos = dds_create_qos(); - CU_ASSERT_PTR_NOT_NULL_FATAL(g_qos); - - g_pol_userdata.value._buffer = dds_alloc(strlen(c_userdata) + 1); - g_pol_userdata.value._length = (uint32_t)strlen(c_userdata) + 1; - g_pol_userdata.value._release = true; - g_pol_userdata.value._maximum = 0; - - g_pol_topicdata.value._buffer = dds_alloc(strlen(c_topicdata) + 1); - g_pol_topicdata.value._length = (uint32_t)strlen(c_topicdata) + 1; - g_pol_topicdata.value._release = true; - g_pol_topicdata.value._maximum = 0; - - g_pol_groupdata.value._buffer = dds_alloc(strlen(c_groupdata) + 1); - g_pol_groupdata.value._length = (uint32_t)strlen(c_groupdata) + 1; - g_pol_groupdata.value._release = true; - g_pol_groupdata.value._maximum = 0; - - g_pol_history.kind = DDS_KEEP_LAST_HISTORY_QOS; - g_pol_history.depth = 1; - - g_pol_resource_limits.max_samples = 1; - g_pol_resource_limits.max_instances = 1; - g_pol_resource_limits.max_samples_per_instance = 1; - - g_pol_presentation.access_scope = DDS_INSTANCE_PRESENTATION_QOS; - g_pol_presentation.coherent_access = true; - g_pol_presentation.ordered_access = true; - - g_pol_lifespan.duration.sec = 10000; - g_pol_lifespan.duration.nanosec = 11000; - - g_pol_deadline.period.sec = 20000; - g_pol_deadline.period.nanosec = 220000; - - g_pol_latency_budget.duration.sec = 30000; - g_pol_latency_budget.duration.nanosec = 33000; - - g_pol_ownership.kind = DDS_EXCLUSIVE_OWNERSHIP_QOS; - - g_pol_ownership_strength.value = 10; - - g_pol_liveliness.kind = DDS_AUTOMATIC_LIVELINESS_QOS; - g_pol_liveliness.lease_duration.sec = 40000; - g_pol_liveliness.lease_duration.nanosec = 44000; - - g_pol_time_based_filter.minimum_separation.sec = 12000; - g_pol_time_based_filter.minimum_separation.nanosec = 55000; - - g_pol_partition.name._buffer = (char**)c_partitions; - g_pol_partition.name._length = 2; - - g_pol_reliability.kind = DDS_RELIABLE_RELIABILITY_QOS; - g_pol_reliability.max_blocking_time.sec = 60000; - g_pol_reliability.max_blocking_time.nanosec = 66000; - - g_pol_transport_priority.value = 42; - - g_pol_destination_order.kind = DDS_BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS; - - g_pol_writer_data_lifecycle.autodispose_unregistered_instances = true; - - g_pol_reader_data_lifecycle.autopurge_disposed_samples_delay.sec = 70000; - g_pol_reader_data_lifecycle.autopurge_disposed_samples_delay.nanosec= 77000; - g_pol_reader_data_lifecycle.autopurge_nowriter_samples_delay.sec = 80000; - g_pol_reader_data_lifecycle.autopurge_nowriter_samples_delay.nanosec = 88000; - - g_pol_durability_service.history_depth = 1; - g_pol_durability_service.history_kind = DDS_KEEP_LAST_HISTORY_QOS; - g_pol_durability_service.max_samples = 12; - g_pol_durability_service.max_instances = 3; - g_pol_durability_service.max_samples_per_instance = 4; - g_pol_durability_service.service_cleanup_delay.sec = 90000; - g_pol_durability_service.service_cleanup_delay.nanosec = 99000; } static void qos_fini(void) { - dds_delete_qos(g_qos); - dds_free(g_pol_userdata.value._buffer); - dds_free(g_pol_groupdata.value._buffer); - dds_free(g_pol_topicdata.value._buffer); } static void @@ -151,11 +46,15 @@ setup(void) g_participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL); CU_ASSERT_FATAL(g_participant > 0); g_topic = dds_create_topic(g_participant, &RoundTripModule_DataType_desc, "RoundTrip", NULL, NULL); - CU_ASSERT_FATAL(g_topic> 0); + CU_ASSERT_FATAL(g_topic > 0); g_subscriber = dds_create_subscriber(g_participant, NULL, NULL); - CU_ASSERT_FATAL(g_subscriber> 0); + CU_ASSERT_FATAL(g_subscriber > 0); g_publisher = dds_create_publisher(g_participant, NULL, NULL); - CU_ASSERT_FATAL(g_publisher> 0); + CU_ASSERT_FATAL(g_publisher > 0); + g_writer = dds_create_writer(g_publisher, g_topic, NULL, NULL); + CU_ASSERT_FATAL(g_writer > 0); + g_reader = dds_create_reader(g_subscriber, g_topic, NULL, NULL); + CU_ASSERT_FATAL(g_reader > 0); } static void @@ -164,15 +63,6 @@ teardown(void) qos_fini(); dds_delete(g_participant); } -#define T_MILLISECOND 1000000ll -#define T_SECOND (1000 * T_MILLISECOND) - -int64_t from_ddsi_duration (DDS_Duration_t x) -{ - int64_t t; - t = (int64_t)x.sec * T_SECOND + x.nanosec; - return t; -} static void check_default_qos_of_builtin_entity(dds_entity_t entity) @@ -187,61 +77,64 @@ check_default_qos_of_builtin_entity(dds_entity_t entity) dds_durability_kind_t durability_kind; dds_presentation_access_scope_kind_t presentation_access_scope_kind; + bool presentation_coherent_access; + bool presentation_ordered_access; dds_ownership_kind_t ownership_kind; dds_liveliness_kind_t liveliness_kind; dds_reliability_kind_t reliability_kind; dds_destination_order_kind_t destination_order_kind; dds_history_kind_t history_kind; + int32_t history_depth; + int32_t resource_limits_max_samples; + int32_t resource_limits_max_instances; + int32_t resource_limits_max_samples_per_instance; char **partitions; uint32_t plen; dds_qos_t *qos = dds_create_qos(); - CU_ASSERT_PTR_NOT_NULL_FATAL(qos); + CU_ASSERT_FATAL(qos != NULL); ret = dds_get_qos(entity, qos); - CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); + CU_ASSERT_FATAL(ret == DDS_RETCODE_OK); dds_qget_durability(qos, &durability_kind); - dds_qget_presentation(qos, &presentation_access_scope_kind, &g_pol_presentation.coherent_access, &g_pol_presentation.ordered_access); + dds_qget_presentation(qos, &presentation_access_scope_kind, &presentation_coherent_access, &presentation_ordered_access); dds_qget_deadline(qos, &deadline); dds_qget_ownership(qos, &ownership_kind); dds_qget_liveliness(qos, &liveliness_kind, &liveliness_lease_duration); dds_qget_time_based_filter(qos, &minimum_separation); dds_qget_reliability(qos, &reliability_kind, &max_blocking_time); dds_qget_destination_order(qos, &destination_order_kind); - dds_qget_history(qos, &history_kind, &g_pol_history.depth); - dds_qget_resource_limits(qos, &g_pol_resource_limits.max_samples, &g_pol_resource_limits.max_instances, &g_pol_resource_limits.max_samples_per_instance); + dds_qget_history(qos, &history_kind, &history_depth); + dds_qget_resource_limits(qos, &resource_limits_max_samples, &resource_limits_max_instances, &resource_limits_max_samples_per_instance); dds_qget_reader_data_lifecycle(qos, &autopurge_nowriter_samples_delay, &autopurge_disposed_samples_delay); dds_qget_partition(qos, &plen, &partitions); // no getter for ENTITY_FACTORY + CU_ASSERT_FATAL((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_SUBSCRIBER || (entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER); if ((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_SUBSCRIBER) { - CU_ASSERT_EQUAL(plen, 1); - if (plen > 0) { - CU_ASSERT_STRING_EQUAL(partitions[0], "__BUILT-IN PARTITION__"); - } - } else if ((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER) { - CU_ASSERT_EQUAL(durability_kind, DDS_DURABILITY_TRANSIENT_LOCAL); - CU_ASSERT_EQUAL(presentation_access_scope_kind, DDS_PRESENTATION_TOPIC); - CU_ASSERT_EQUAL(g_pol_presentation.coherent_access, false); - CU_ASSERT_EQUAL(g_pol_presentation.ordered_access, false); - CU_ASSERT_EQUAL(deadline, DDS_INFINITY); - CU_ASSERT_EQUAL(ownership_kind, DDS_OWNERSHIP_SHARED); - CU_ASSERT_EQUAL(liveliness_kind, DDS_LIVELINESS_AUTOMATIC); - CU_ASSERT_EQUAL(minimum_separation, 0); - CU_ASSERT_EQUAL(reliability_kind, DDS_RELIABILITY_RELIABLE); - CU_ASSERT_EQUAL(max_blocking_time, DDS_MSECS(100)); - CU_ASSERT_EQUAL(destination_order_kind, DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP); - CU_ASSERT_EQUAL(history_kind, DDS_HISTORY_KEEP_LAST); - CU_ASSERT_EQUAL(g_pol_history.depth, 1); - CU_ASSERT_EQUAL(g_pol_resource_limits.max_instances, DDS_LENGTH_UNLIMITED); - CU_ASSERT_EQUAL(g_pol_resource_limits.max_samples, DDS_LENGTH_UNLIMITED); - CU_ASSERT_EQUAL(g_pol_resource_limits.max_samples_per_instance, DDS_LENGTH_UNLIMITED); - CU_ASSERT_EQUAL(autopurge_nowriter_samples_delay, DDS_INFINITY); - CU_ASSERT_EQUAL(autopurge_disposed_samples_delay, DDS_INFINITY); + CU_ASSERT_FATAL(plen == 1); + CU_ASSERT_STRING_EQUAL_FATAL(partitions[0], "__BUILT-IN PARTITION__"); } else { - CU_FAIL_FATAL("Unsupported entity kind"); + CU_ASSERT_FATAL(durability_kind == DDS_DURABILITY_TRANSIENT_LOCAL); + CU_ASSERT_FATAL(presentation_access_scope_kind == DDS_PRESENTATION_TOPIC); + CU_ASSERT_FATAL(presentation_coherent_access == false); + CU_ASSERT_FATAL(presentation_ordered_access == false); + CU_ASSERT_FATAL(deadline == DDS_INFINITY); + CU_ASSERT_FATAL(ownership_kind == DDS_OWNERSHIP_SHARED); + CU_ASSERT_FATAL(liveliness_kind == DDS_LIVELINESS_AUTOMATIC); + CU_ASSERT_FATAL(minimum_separation == 0); + CU_ASSERT_FATAL(reliability_kind == DDS_RELIABILITY_RELIABLE); + CU_ASSERT_FATAL(max_blocking_time == DDS_MSECS(100)); + CU_ASSERT_FATAL(destination_order_kind == DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP); + CU_ASSERT_FATAL(history_kind == DDS_HISTORY_KEEP_LAST); + CU_ASSERT_FATAL(history_depth == 1); + CU_ASSERT_FATAL(resource_limits_max_instances == DDS_LENGTH_UNLIMITED); + CU_ASSERT_FATAL(resource_limits_max_samples == DDS_LENGTH_UNLIMITED); + CU_ASSERT_FATAL(resource_limits_max_samples_per_instance == DDS_LENGTH_UNLIMITED); + CU_ASSERT_FATAL(autopurge_nowriter_samples_delay == DDS_INFINITY); + CU_ASSERT_FATAL(autopurge_disposed_samples_delay == DDS_INFINITY); } if (plen > 0) { for (uint32_t i = 0; i < plen; i++) { @@ -252,29 +145,6 @@ check_default_qos_of_builtin_entity(dds_entity_t entity) dds_delete_qos(qos); } -static dds_entity_t builtin_topic_handles[10]; - -CU_Test(ddsc_builtin_topics, types_allocation) -{ -#define TEST_ALLOC(type) do { \ - DDS_##type##BuiltinTopicData *data = DDS_##type##BuiltinTopicData__alloc(); \ - CU_ASSERT_PTR_NOT_NULL(data); \ - DDS_##type##BuiltinTopicData_free(data, DDS_FREE_ALL); \ - } while(0) - - TEST_ALLOC(Participant); - TEST_ALLOC(CMParticipant); - TEST_ALLOC(Type); - TEST_ALLOC(Topic); - TEST_ALLOC(Publication); - TEST_ALLOC(CMPublisher); - TEST_ALLOC(Subscription); - TEST_ALLOC(CMSubscriber); - TEST_ALLOC(CMDataWriter); - TEST_ALLOC(CMDataReader); -#undef TEST_ALLOC -} - CU_Test(ddsc_builtin_topics, availability_builtin_topics, .init = setup, .fini = teardown) { dds_entity_t topic; @@ -285,259 +155,101 @@ CU_Test(ddsc_builtin_topics, availability_builtin_topics, .init = setup, .fini = topic = dds_find_topic(g_participant, "DCPSTopic"); CU_ASSERT_FATAL(topic < 0); //TODO CHAM-347: dds_delete(topic); - topic = dds_find_topic(g_participant, "DCPSType"); - CU_ASSERT_FATAL(topic < 0); - //TODO CHAM-347: dds_delete(topic); topic = dds_find_topic(g_participant, "DCPSSubscription"); - CU_ASSERT_FATAL(topic < 0); - //TODO CHAM-347: dds_delete(topic); - topic = dds_find_topic(g_participant, "DCSPPublication"); - CU_ASSERT_FATAL(topic < 0); - //TODO CHAM-347: dds_delete(topic); + CU_ASSERT_FATAL(topic > 0); + dds_delete(topic); + topic = dds_find_topic(g_participant, "DCPSPublication"); + CU_ASSERT_FATAL(topic > 0); + dds_delete(topic); } CU_Test(ddsc_builtin_topics, read_publication_data, .init = setup, .fini = teardown) { dds_entity_t reader; -#if 0 /* disabled pending CHAM-347 */ dds_return_t ret; - DDS_PublicationBuiltinTopicData *data; -#endif + dds_builtintopic_endpoint_t *data; void *samples[MAX_SAMPLES]; - reader = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSPUBLICATION, NULL, NULL); CU_ASSERT_FATAL(reader > 0); - samples[0] = DDS_PublicationBuiltinTopicData__alloc(); -#if 0 /* disabled pending CHAM-347 */ + samples[0] = NULL; ret = dds_read(reader, samples, g_info, MAX_SAMPLES, MAX_SAMPLES); + data = samples[0]; CU_ASSERT_FATAL(ret > 0); - - data = (DDS_PublicationBuiltinTopicData *)samples; - CU_ASSERT_STRING_EQUAL_FATAL(data->topic_name, "DCPSPublication"); -#endif - - DDS_PublicationBuiltinTopicData_free(samples[0], DDS_FREE_ALL); -} - -CU_Test(ddsc_builtin_topics, create_reader) -{ - dds_entity_t participant; - dds_entity_t t1; - - /* Create a participant */ - participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL); - CU_ASSERT_FATAL(participant > 0); - - /* - * The topics are created by the middleware as soon as a participant - * is created. - */ -#define TEST_FIND(p, t) do { \ - t1 = dds_find_topic(p, t); \ - CU_ASSERT(t1 > 0); \ - dds_delete(t1); \ - } while(0); - - /* A builtin-topic proxy is created 'on demand' and should not exist before a reader is created for it */ - TEST_FIND(participant, "DCPSParticipant"); - TEST_FIND(participant, "CMParticipant"); -#undef TEST_FIND - - /* - * TODO CHAM-347: Not all builtin topics are created at the start. - */ -#define TEST_NOTFOUND(p, t) do { \ - t1 = dds_find_topic(p, t); \ - CU_ASSERT(t1 < 0); \ - } while(0); - - /* A builtin-topic proxy is created 'on demand' and should not exist before a reader is created for it */ - TEST_NOTFOUND(participant, "DCPSType"); - TEST_NOTFOUND(participant, "DCPSTopic"); - TEST_NOTFOUND(participant, "DCPSPublication"); - TEST_NOTFOUND(participant, "CMPublisher"); - TEST_NOTFOUND(participant, "DCPSSubscription"); - TEST_NOTFOUND(participant, "CMSubscriber"); - TEST_NOTFOUND(participant, "CMDataWriter"); - TEST_NOTFOUND(participant, "CMDataReader"); -#undef TEST_NOTFOUND - - /* A reader is created by providing a special builtin-topic handle */ - { - dds_entity_t readers[10]; - dds_entity_t builtin_subscriber, s; - - builtin_topic_handles[0] = DDS_BUILTIN_TOPIC_DCPSPARTICIPANT; - builtin_topic_handles[1] = DDS_BUILTIN_TOPIC_CMPARTICIPANT; - builtin_topic_handles[2] = DDS_BUILTIN_TOPIC_DCPSTYPE; - builtin_topic_handles[3] = DDS_BUILTIN_TOPIC_DCPSTOPIC; - builtin_topic_handles[4] = DDS_BUILTIN_TOPIC_DCPSPUBLICATION; - builtin_topic_handles[5] = DDS_BUILTIN_TOPIC_CMPUBLISHER; - builtin_topic_handles[6] = DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION; - builtin_topic_handles[7] = DDS_BUILTIN_TOPIC_CMSUBSCRIBER; - builtin_topic_handles[8] = DDS_BUILTIN_TOPIC_CMDATAWRITER; - builtin_topic_handles[9] = DDS_BUILTIN_TOPIC_CMDATAREADER; - - - for (int i = 0; i < 10; i++) { - readers[i] = dds_create_reader(participant, builtin_topic_handles[i], NULL, NULL); - CU_ASSERT(readers[i]> 0); - - if (i == 0) { - /* Check the parent of reader is a subscriber */ - builtin_subscriber = dds_get_parent(readers[i]); - CU_ASSERT_FATAL(builtin_subscriber > 0); - CU_ASSERT_EQUAL_FATAL(builtin_subscriber & DDS_ENTITY_KIND_MASK, DDS_KIND_SUBSCRIBER); - } else { - /* Check the parent of reader equals parent of first reader */ - s = dds_get_parent(readers[i]); - CU_ASSERT_FATAL(s > 0); - CU_ASSERT_EQUAL_FATAL(s, builtin_subscriber); - //dds_delete(s); - } - } - } - -#define TEST_FOUND(p, t) do { \ - t1 = dds_find_topic(p, t); \ - CU_ASSERT(t1 > 0); \ - if (t1 > 0) { \ - dds_delete(t1); \ - } \ - } while(0); - - /* Builtin-topics proxies should now be created */ - TEST_FOUND(participant, "DCPSParticipant"); - TEST_FOUND(participant, "CMParticipant"); - TEST_FOUND(participant, "DCPSType"); - TEST_FOUND(participant, "DCPSTopic"); - TEST_FOUND(participant, "DCPSPublication"); - TEST_FOUND(participant, "CMPublisher"); - TEST_FOUND(participant, "DCPSSubscription"); - TEST_FOUND(participant, "CMSubscriber"); - TEST_FOUND(participant, "CMDataWriter"); - TEST_FOUND(participant, "CMDataReader"); -#undef TEST_FOUND - - dds_delete(participant); + CU_ASSERT_STRING_EQUAL_FATAL(data->topic_name, "RoundTrip"); + dds_return_loan(reader, samples, ret); } CU_Test(ddsc_builtin_topics, read_subscription_data, .init = setup, .fini = teardown) { dds_entity_t reader; -#if 0 /* not supported yet */ dds_return_t ret; - DDS_SubscriptionBuiltinTopicData *data; -#endif void * samples[MAX_SAMPLES]; + const char *exp[] = { "DCPSSubscription", "RoundTrip" }; + unsigned seen = 0; + dds_qos_t *qos; reader = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION, NULL, NULL); - CU_ASSERT_FATAL(reader> 0); + CU_ASSERT_FATAL(reader > 0); - samples[0] = DDS_SubscriptionBuiltinTopicData__alloc(); - -#if 0 /* not supported yet */ + samples[0] = NULL; ret = dds_read(reader, samples, g_info, MAX_SAMPLES, MAX_SAMPLES); - CU_ASSERT_FATAL(ret> 0); + CU_ASSERT_FATAL(ret == 2); + qos = dds_create_qos(); + for (int i = 0; i < ret; i++) { + dds_builtintopic_endpoint_t *data = samples[i]; + for (size_t j = 0; j < sizeof (exp) / sizeof (exp[0]); j++) { + if (strcmp (data->topic_name, exp[j]) == 0) { + seen |= 1u << j; + dds_return_t get_qos_ret = dds_get_qos(j == 0 ? reader : g_reader, qos); + CU_ASSERT_FATAL(get_qos_ret == DDS_RETCODE_OK); + const bool eq = dds_qos_equal(qos, data->qos); + CU_ASSERT_FATAL(eq); + } + } + } + CU_ASSERT_FATAL(seen == 3); + dds_delete_qos(qos); - data = (DDS_SubscriptionBuiltinTopicData *)samples; - CU_ASSERT_STRING_EQUAL_FATAL(data->topic_name, "DCPSSubscription"); -#endif - - DDS_SubscriptionBuiltinTopicData_free(samples[0], DDS_FREE_ALL); + dds_return_loan(reader, samples, ret); } CU_Test(ddsc_builtin_topics, read_participant_data, .init = setup, .fini = teardown) { dds_entity_t reader; dds_return_t ret; + //dds_builtintopic_participant_t *data; void * samples[MAX_SAMPLES]; reader = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSPARTICIPANT, NULL, NULL); CU_ASSERT_FATAL(reader > 0); - samples[0] = DDS_ParticipantBuiltinTopicData__alloc(); - + samples[0] = NULL; ret = dds_read(reader, samples, g_info, MAX_SAMPLES, MAX_SAMPLES); CU_ASSERT_FATAL(ret > 0); -#if 0 - { - DDS_ParticipantBuiltinTopicData *data = (DDS_ParticipantBuiltinTopicData*)samples[0]; - } -#endif - - DDS_ParticipantBuiltinTopicData_free(samples[0], DDS_FREE_ALL); -} - -CU_Test(ddsc_builtin_topics, read_cmparticipant_data, .init = setup, .fini = teardown) -{ - dds_entity_t reader; - dds_return_t ret; - void * samples[MAX_SAMPLES]; - - reader = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_CMPARTICIPANT, NULL, NULL); - CU_ASSERT_FATAL(reader > 0); - - samples[0] = DDS_CMParticipantBuiltinTopicData__alloc(); - - ret = dds_read(reader, samples, g_info, MAX_SAMPLES, MAX_SAMPLES); - CU_ASSERT_FATAL(ret > 0); -#if 0 - { - DDS_CMParticipantBuiltinTopicData *data = (DDS_CMParticipantBuiltinTopicData*)samples[0]; - } -#endif - - DDS_CMParticipantBuiltinTopicData_free(samples[0], DDS_FREE_ALL); + dds_return_loan(reader, samples, ret); } CU_Test(ddsc_builtin_topics, read_topic_data, .init = setup, .fini = teardown) { - dds_entity_t reader; #if 0 /* disabled pending CHAM-347 */ + dds_entity_t reader; dds_return_t ret; DDS_TopicBuiltinTopicData *data; -#endif void * samples[MAX_SAMPLES]; - reader = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSTOPIC, NULL, NULL); CU_ASSERT_FATAL(reader > 0); - samples[0] = DDS_TopicBuiltinTopicData__alloc(); -#if 0 /* disabled pending CHAM-347 */ - ret = dds_read(reader, samples, g_info, MAX_SAMPLES, MAX_SAMPLES); - CU_ASSERT_FATAL(ret> 0); - - data = (DDS_TopicBuiltinTopicData *)samples; - CU_ASSERT_STRING_EQUAL_FATAL(data->name, "DCPSSubscription"); -#endif - DDS_ParticipantBuiltinTopicData_free(samples[0], DDS_FREE_ALL); -} - -CU_Test(ddsc_builtin_topics, read_type_data, .init = setup, .fini = teardown) -{ - dds_entity_t reader; -#if 0 /* disabled pending CHAM-347 */ - dds_return_t ret; - DDS_TypeBuiltinTopicData *data; -#endif - void * samples[MAX_SAMPLES]; - - reader = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSTYPE, NULL, NULL); - CU_ASSERT_FATAL(reader > 0); - - samples[0] = DDS_TypeBuiltinTopicData__alloc(); -#if 0 /* disabled pending CHAM-347 */ + samples[0] = NULL; ret = dds_read(reader, samples, g_info, MAX_SAMPLES, MAX_SAMPLES); CU_ASSERT_FATAL(ret > 0); - data = (DDS_TypeBuiltinTopicData *)samples; - CU_ASSERT_STRING_EQUAL_FATAL(data->name, "DCPSType"); + data = (DDS_TopicBuiltinTopicData *)samples; + CU_ASSERT_STRING_EQUAL_FATAL(data->name, "DCPSSubscription"); + dds_return_loan(reader, samples, ret); #endif - DDS_TypeBuiltinTopicData_free(samples[0], DDS_FREE_ALL); } CU_Test(ddsc_builtin_topics, same_subscriber, .init = setup, .fini = teardown) @@ -551,11 +263,10 @@ CU_Test(ddsc_builtin_topics, same_subscriber, .init = setup, .fini = teardown) dds_entity_t participant_rdr; dds_entity_t participant_subscriber; +#if 0 dds_entity_t topic_rdr; dds_entity_t topic_subscriber; - - dds_entity_t type_rdr; - dds_entity_t type_subscriber; +#endif subscription_rdr = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION, NULL, NULL); CU_ASSERT_FATAL(subscription_rdr > 0); @@ -567,28 +278,23 @@ CU_Test(ddsc_builtin_topics, same_subscriber, .init = setup, .fini = teardown) publication_subscriber = dds_get_parent(publication_rdr); CU_ASSERT_FATAL(publication_subscriber > 0); - CU_ASSERT_EQUAL_FATAL(subscription_subscriber, publication_subscriber); + CU_ASSERT_FATAL(subscription_subscriber == publication_subscriber); participant_rdr = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSPARTICIPANT, NULL, NULL); CU_ASSERT_FATAL(participant_rdr > 0); participant_subscriber = dds_get_parent(participant_rdr); CU_ASSERT_FATAL(participant_subscriber > 0); - CU_ASSERT_EQUAL_FATAL(publication_subscriber, participant_subscriber); + CU_ASSERT_FATAL(publication_subscriber == participant_subscriber); +#if 0 topic_rdr = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSTOPIC, NULL, NULL); CU_ASSERT_FATAL(topic_rdr > 0); topic_subscriber = dds_get_parent(topic_rdr); CU_ASSERT_FATAL(topic_subscriber > 0); - CU_ASSERT_EQUAL_FATAL(participant_subscriber, topic_subscriber); - - type_rdr = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSTYPE, NULL, NULL); - CU_ASSERT_FATAL(type_rdr > 0); - type_subscriber = dds_get_parent(type_rdr); - CU_ASSERT_FATAL(type_subscriber > 0); - - CU_ASSERT_EQUAL_FATAL(topic_subscriber, type_subscriber); + CU_ASSERT_FATAL(participant_subscriber == topic_subscriber); +#endif } CU_Test(ddsc_builtin_topics, builtin_qos, .init = setup, .fini = teardown) @@ -604,240 +310,3 @@ CU_Test(ddsc_builtin_topics, builtin_qos, .init = setup, .fini = teardown) CU_ASSERT_FATAL(dds_sub_subscriber > 0); check_default_qos_of_builtin_entity(dds_sub_subscriber); } - -CU_Test(ddsc_builtin_topics, datareader_qos, .init = setup, .fini = teardown) -{ - dds_entity_t rdr; - dds_entity_t subscription_rdr; - void * subscription_samples[MAX_SAMPLES]; -#if 0 /* disabled pending CHAM-347 */ - dds_return_t ret; - DDS_SubscriptionBuiltinTopicData *subscription_data; -#endif - - // Set some qos' which differ from the default - dds_qset_durability(g_qos, (dds_durability_kind_t)g_pol_durability.kind); - dds_qset_deadline(g_qos, from_ddsi_duration(g_pol_deadline.period)); - dds_qset_latency_budget(g_qos, from_ddsi_duration(g_pol_latency_budget.duration)); - dds_qset_liveliness(g_qos, (dds_liveliness_kind_t)g_pol_liveliness.kind, from_ddsi_duration(g_pol_liveliness.lease_duration)); - dds_qset_reliability(g_qos, (dds_reliability_kind_t)g_pol_reliability.kind, from_ddsi_duration(g_pol_reliability.max_blocking_time)); - dds_qset_ownership(g_qos, (dds_ownership_kind_t)g_pol_ownership.kind); - dds_qset_destination_order(g_qos, (dds_destination_order_kind_t)g_pol_destination_order.kind); - dds_qset_userdata(g_qos, g_pol_userdata.value._buffer, g_pol_userdata.value._length); - dds_qset_time_based_filter(g_qos, from_ddsi_duration(g_pol_time_based_filter.minimum_separation)); - dds_qset_presentation(g_qos, (dds_presentation_access_scope_kind_t)g_pol_presentation.access_scope, g_pol_presentation.coherent_access, g_pol_presentation.ordered_access); - dds_qset_partition(g_qos, g_pol_partition.name._length, c_partitions); - dds_qset_topicdata(g_qos, g_pol_topicdata.value._buffer, g_pol_topicdata.value._length); - dds_qset_groupdata(g_qos, g_pol_groupdata.value._buffer, g_pol_groupdata.value._length); - - rdr = dds_create_reader(g_subscriber, g_topic, g_qos, NULL); - CU_ASSERT_FATAL(rdr > 0); - - subscription_samples[0] = DDS_SubscriptionBuiltinTopicData__alloc(); - - subscription_rdr = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION, NULL, NULL); - CU_ASSERT_FATAL(subscription_rdr > 0); -#if 0 /* disabled pending CHAM-347 */ - ret = dds_read(subscription_rdr, subscription_samples, g_info, MAX_SAMPLES, MAX_SAMPLES); - CU_ASSERT_FATAL(ret > 0); - - // Check the QOS settings of the 'remote' qos' - subscription_data = (DDS_SubscriptionBuiltinTopicData *)subscription_samples[0]; - - CU_ASSERT_STRING_EQUAL_FATAL(subscription_data->topic_name, "RoundTrip"); - CU_ASSERT_STRING_EQUAL_FATAL(subscription_data->type_name, "RoundTripModule::DataType"); - CU_ASSERT_EQUAL_FATAL(subscription_data->durability.kind, g_pol_durability.kind); - CU_ASSERT_EQUAL_FATAL(subscription_data->deadline.period.sec, g_pol_deadline.period.sec); - CU_ASSERT_EQUAL_FATAL(subscription_data->deadline.period.nanosec, g_pol_deadline.period.nanosec); - CU_ASSERT_EQUAL_FATAL(subscription_data->latency_budget.duration.sec, g_pol_latency_budget.duration.sec); - CU_ASSERT_EQUAL_FATAL(subscription_data->latency_budget.duration.nanosec, g_pol_latency_budget.duration.nanosec); - CU_ASSERT_EQUAL_FATAL(subscription_data->liveliness.kind, g_pol_liveliness.kind); - CU_ASSERT_EQUAL_FATAL(subscription_data->liveliness.lease_duration.sec, g_pol_liveliness.lease_duration.sec); - CU_ASSERT_EQUAL_FATAL(subscription_data->liveliness.lease_duration.nanosec, g_pol_liveliness.lease_duration.nanosec); - CU_ASSERT_EQUAL_FATAL(subscription_data->reliability.kind, g_pol_reliability.kind); - CU_ASSERT_EQUAL_FATAL(subscription_data->reliability.max_blocking_time.sec, g_pol_reliability.max_blocking_time.sec); - CU_ASSERT_EQUAL_FATAL(subscription_data->reliability.max_blocking_time.nanosec, g_pol_reliability.max_blocking_time.nanosec); - CU_ASSERT_EQUAL_FATAL(subscription_data->ownership.kind, g_pol_ownership.kind); - CU_ASSERT_EQUAL_FATAL(subscription_data->destination_order.kind, g_pol_destination_order.kind); - CU_ASSERT_EQUAL_FATAL(subscription_data->user_data.value._buffer, g_pol_userdata.value._buffer); - CU_ASSERT_EQUAL_FATAL(subscription_data->user_data.value._length, g_pol_userdata.value._length); - CU_ASSERT_EQUAL_FATAL(subscription_data->time_based_filter.minimum_separation.sec, g_pol_time_based_filter.minimum_separation.sec); - CU_ASSERT_EQUAL_FATAL(subscription_data->time_based_filter.minimum_separation.nanosec, g_pol_time_based_filter.minimum_separation.nanosec); - CU_ASSERT_EQUAL_FATAL(subscription_data->presentation.access_scope, g_pol_presentation.access_scope); - CU_ASSERT_EQUAL_FATAL(subscription_data->presentation.coherent_access, g_pol_presentation.coherent_access); - CU_ASSERT_EQUAL_FATAL(subscription_data->presentation.ordered_access, g_pol_presentation.ordered_access); - - CU_ASSERT_EQUAL_FATAL(subscription_data->partition.name._length, g_pol_partition.name._length); - for (uint32_t i = 0; i < subscription_data->partition.name._length; ++i) - { - CU_ASSERT_STRING_EQUAL_FATAL(subscription_data->partition.name._buffer[i], c_partitions[i]); - } - - CU_ASSERT_STRING_EQUAL_FATAL(subscription_data->topic_data.value._buffer, g_pol_topicdata.value._buffer); - CU_ASSERT_EQUAL_FATAL(subscription_data->topic_data.value._length, g_pol_topicdata.value._length); - CU_ASSERT_STRING_EQUAL_FATAL(subscription_data->group_data.value._buffer, g_pol_groupdata.value._buffer); - CU_ASSERT_EQUAL_FATAL(subscription_data->group_data.value._length, g_pol_groupdata.value._length); -#endif - DDS_SubscriptionBuiltinTopicData_free(subscription_samples[0], DDS_FREE_ALL); -} - -CU_Test(ddsc_builtin_topics, datawriter_qos, .init = setup, .fini = teardown) -{ - dds_entity_t wrtr; - dds_entity_t publication_rdr; -#if 0 /* disabled pending CHAM-347 */ - dds_return_t ret; - DDS_PublicationBuiltinTopicData *publication_data; -#endif - void * publication_samples[MAX_SAMPLES]; - - - dds_qset_durability(g_qos, (dds_durability_kind_t)g_pol_durability.kind); - dds_qset_deadline(g_qos, from_ddsi_duration(g_pol_deadline.period)); - dds_qset_latency_budget(g_qos, from_ddsi_duration(g_pol_latency_budget.duration)); - dds_qset_liveliness(g_qos, (dds_liveliness_kind_t)g_pol_liveliness.kind, from_ddsi_duration(g_pol_liveliness.lease_duration)); - dds_qset_reliability(g_qos, (dds_reliability_kind_t)g_pol_reliability.kind, from_ddsi_duration(g_pol_reliability.max_blocking_time)); - dds_qset_lifespan(g_qos, from_ddsi_duration(g_pol_lifespan.duration)); - dds_qset_destination_order(g_qos, (dds_destination_order_kind_t)g_pol_destination_order.kind); - dds_qset_userdata(g_qos, g_pol_userdata.value._buffer, g_pol_userdata.value._length); - dds_qset_ownership(g_qos, (dds_ownership_kind_t)g_pol_ownership.kind); - dds_qset_ownership_strength(g_qos, g_pol_ownership_strength.value); - dds_qset_presentation(g_qos, (dds_presentation_access_scope_kind_t)g_pol_presentation.access_scope, g_pol_presentation.coherent_access, g_pol_presentation.ordered_access); - dds_qset_partition(g_qos, g_pol_partition.name._length, c_partitions); - dds_qset_topicdata(g_qos, g_pol_topicdata.value._buffer, g_pol_topicdata.value._length); - - wrtr = dds_create_writer(g_publisher, g_topic, g_qos, NULL); - CU_ASSERT_FATAL(wrtr > 0); - - publication_samples[0] = DDS_PublicationBuiltinTopicData__alloc(); - - publication_rdr = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSPUBLICATION, NULL, NULL); - CU_ASSERT_FATAL(publication_rdr > 0); - -#if 0 /* disabled pending CHAM-347 */ - ret = dds_read(publication_rdr, publication_samples, g_info, MAX_SAMPLES, MAX_SAMPLES); - CU_ASSERT_FATAL(ret> 0); - - // Check the QOS settings of the 'remote' qos' - publication_data = (DDS_PublicationBuiltinTopicData *)publication_samples[0]; - - CU_ASSERT_STRING_EQUAL_FATAL(publication_data->topic_name, "RoundTrip"); - CU_ASSERT_STRING_EQUAL_FATAL(publication_data->type_name, "RoundTripModule::DataType"); - CU_ASSERT_EQUAL_FATAL(publication_data->durability.kind, g_pol_durability.kind); - CU_ASSERT_EQUAL_FATAL(publication_data->deadline.period.sec, g_pol_deadline.period.sec); - CU_ASSERT_EQUAL_FATAL(publication_data->deadline.period.nanosec, g_pol_deadline.period.nanosec); - CU_ASSERT_EQUAL_FATAL(publication_data->latency_budget.duration.sec, g_pol_latency_budget.duration.sec); - CU_ASSERT_EQUAL_FATAL(publication_data->latency_budget.duration.nanosec, g_pol_latency_budget.duration.nanosec); - CU_ASSERT_EQUAL_FATAL(publication_data->liveliness.kind, g_pol_liveliness.kind); - CU_ASSERT_EQUAL_FATAL(publication_data->liveliness.lease_duration.sec, g_pol_liveliness.lease_duration.sec); - CU_ASSERT_EQUAL_FATAL(publication_data->liveliness.lease_duration.nanosec, g_pol_liveliness.lease_duration.nanosec); - CU_ASSERT_EQUAL_FATAL(publication_data->reliability.kind, g_pol_reliability.kind); - CU_ASSERT_EQUAL_FATAL(publication_data->reliability.max_blocking_time.sec, g_pol_reliability.max_blocking_time.sec); - CU_ASSERT_EQUAL_FATAL(publication_data->reliability.max_blocking_time.nanosec, g_pol_reliability.max_blocking_time.nanosec); - CU_ASSERT_EQUAL_FATAL(publication_data->lifespan.duration.sec, g_pol_lifespan.duration.sec); - CU_ASSERT_EQUAL_FATAL(publication_data->lifespan.duration.nanosec, g_pol_lifespan.duration.nanosec); - CU_ASSERT_EQUAL_FATAL(publication_data->destination_order.kind, g_pol_destination_order.kind); - CU_ASSERT_EQUAL_FATAL(publication_data->user_data.value._buffer, g_pol_userdata.value._buffer); - CU_ASSERT_EQUAL_FATAL(publication_data->user_data.value._length, g_pol_userdata.value._length); - CU_ASSERT_EQUAL_FATAL(publication_data->ownership.kind, g_pol_ownership.kind); - CU_ASSERT_EQUAL_FATAL(publication_data->ownership_strength.value, g_pol_ownership_strength.value); - CU_ASSERT_EQUAL_FATAL(publication_data->presentation.access_scope, g_pol_presentation.access_scope); - CU_ASSERT_EQUAL_FATAL(publication_data->presentation.coherent_access, g_pol_presentation.coherent_access); - CU_ASSERT_EQUAL_FATAL(publication_data->presentation.ordered_access, g_pol_presentation.ordered_access); - - CU_ASSERT_EQUAL_FATAL(publication_data->partition.name._length, g_pol_partition.name._length); - for (uint32_t i = 0; i < publication_data->partition.name._length; ++i) - { - CU_ASSERT_STRING_EQUAL_FATAL(publication_data->partition.name._buffer[i], c_partitions[i]); - } - - CU_ASSERT_STRING_EQUAL_FATAL(publication_data->topic_data.value._buffer, g_pol_topicdata.value._buffer); - CU_ASSERT_EQUAL_FATAL(publication_data->topic_data.value._length, g_pol_topicdata.value._length); - CU_ASSERT_STRING_EQUAL_FATAL(publication_data->group_data.value._buffer, g_pol_groupdata.value._buffer); - CU_ASSERT_EQUAL_FATAL(publication_data->group_data.value._length, g_pol_groupdata.value._length); -#endif - DDS_PublicationBuiltinTopicData_free(publication_samples[0], DDS_FREE_ALL); -} - -CU_Test(ddsc_builtin_topics, topic_qos, .init = setup, .fini = teardown) -{ - dds_entity_t tpc; - dds_entity_t topic_rdr; - -#if 0 /* disabled pending CHAM-347 */ - dds_return_t ret; - DDS_TopicBuiltinTopicData *topic_data; -#endif - - void * topic_samples[MAX_SAMPLES]; - - dds_qset_durability(g_qos, (dds_durability_kind_t)g_pol_durability.kind); - dds_qset_durability_service(g_qos, - from_ddsi_duration(g_pol_durability_service.service_cleanup_delay), - (dds_history_kind_t)g_pol_durability_service.history_kind, - g_pol_durability_service.history_depth, - g_pol_durability_service.max_samples, - g_pol_durability_service.max_instances, - g_pol_durability_service.max_samples_per_instance); - dds_qset_deadline(g_qos, from_ddsi_duration(g_pol_deadline.period)); - dds_qset_latency_budget(g_qos, from_ddsi_duration(g_pol_latency_budget.duration)); - dds_qset_liveliness(g_qos, (dds_liveliness_kind_t)g_pol_liveliness.kind, from_ddsi_duration(g_pol_liveliness.lease_duration)); - dds_qset_reliability(g_qos, (dds_reliability_kind_t)g_pol_reliability.kind, from_ddsi_duration(g_pol_reliability.max_blocking_time)); - dds_qset_transport_priority(g_qos, g_pol_transport_priority.value); - dds_qset_lifespan(g_qos, from_ddsi_duration(g_pol_lifespan.duration)); - dds_qset_destination_order(g_qos, (dds_destination_order_kind_t)g_pol_destination_order.kind); - dds_qset_history(g_qos, (dds_history_kind_t)g_pol_history.kind, g_pol_history.depth); - dds_qset_resource_limits(g_qos, g_pol_resource_limits.max_samples, g_pol_resource_limits.max_instances, - g_pol_resource_limits.max_samples_per_instance); - dds_qset_ownership(g_qos, (dds_ownership_kind_t)g_pol_ownership.kind); - dds_qset_topicdata(g_qos, g_pol_topicdata.value._buffer, g_pol_topicdata.value._length); - - - tpc = dds_create_topic(g_participant, &Space_Type1_desc, "SpaceType1", g_qos, NULL); - CU_ASSERT_FATAL(tpc > 0); - - topic_samples[0] = DDS_PublicationBuiltinTopicData__alloc(); - - topic_rdr = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSTOPIC, NULL, NULL); - CU_ASSERT_FATAL(topic_rdr > 0 ); -#if 0 /* disabled pending CHAM-347 */ - ret = dds_read(topic_rdr, topic_samples, g_info, MAX_SAMPLES, MAX_SAMPLES); - CU_ASSERT_FATAL(ret > 0); - - topic_data = (DDS_TopicBuiltinTopicData *)topic_samples[0]; - - CU_ASSERT_STRING_EQUAL_FATAL(topic_data->name, "SpaceType1"); - CU_ASSERT_STRING_EQUAL_FATAL(topic_data->type_name, "RoundTripModule::DataType"); - CU_ASSERT_EQUAL_FATAL(topic_data->durability.kind, g_pol_durability.kind); - CU_ASSERT_EQUAL_FATAL(topic_data->durability_service.service_cleanup_delay.sec, g_pol_durability_service.service_cleanup_delay.sec); - CU_ASSERT_EQUAL(topic_data->durability_service.service_cleanup_delay.nanosec, g_pol_durability_service.service_cleanup_delay.nanosec); - CU_ASSERT_EQUAL_FATAL(topic_data->durability_service.history_kind, g_pol_durability_service.history_kind); - CU_ASSERT_EQUAL_FATAL(topic_data->durability_service.history_depth, g_pol_durability_service.history_depth); - CU_ASSERT_EQUAL_FATAL(topic_data->durability_service.max_samples, g_pol_durability_service.max_samples); - CU_ASSERT_EQUAL_FATAL(topic_data->durability_service.max_instances, g_pol_durability_service.max_instances); - CU_ASSERT_EQUAL_FATAL(topic_data->durability_service.max_samples_per_instance, g_pol_durability_service.max_samples_per_instance); - CU_ASSERT_EQUAL_FATAL(topic_data->deadline.period.sec, g_pol_deadline.period.sec); - CU_ASSERT_EQUAL_FATAL(topic_data->deadline.period.nanosec, g_pol_deadline.period.nanosec); - CU_ASSERT_EQUAL_FATAL(topic_data->latency_budget.duration.sec, g_pol_latency_budget.duration.sec); - CU_ASSERT_EQUAL_FATAL(topic_data->latency_budget.duration.nanosec, g_pol_latency_budget.duration.nanosec); - CU_ASSERT_EQUAL_FATAL(topic_data->liveliness.kind, g_pol_liveliness.kind); - CU_ASSERT_EQUAL_FATAL(topic_data->liveliness.lease_duration.sec, g_pol_liveliness.lease_duration.sec); - CU_ASSERT_EQUAL_FATAL(topic_data->liveliness.lease_duration.nanosec, g_pol_liveliness.lease_duration.nanosec); - CU_ASSERT_EQUAL_FATAL(topic_data->reliability.kind, g_pol_reliability.kind); - CU_ASSERT_EQUAL_FATAL(topic_data->reliability.max_blocking_time.sec, g_pol_reliability.max_blocking_time.sec); - CU_ASSERT_EQUAL_FATAL(topic_data->reliability.max_blocking_time.nanosec, g_pol_reliability.max_blocking_time.nanosec); - CU_ASSERT_EQUAL_FATAL(topic_data->transport_priority.value, g_pol_transport_priority.value); - CU_ASSERT_EQUAL_FATAL(topic_data->lifespan.duration.sec, g_pol_lifespan.duration.sec); - CU_ASSERT_EQUAL_FATAL(topic_data->lifespan.duration.nanosec, g_pol_lifespan.duration.nanosec); - CU_ASSERT_EQUAL_FATAL(topic_data->destination_order.kind, g_pol_destination_order.kind); - CU_ASSERT_EQUAL_FATAL(topic_data->history.kind, g_pol_history.kind); - CU_ASSERT_EQUAL_FATAL(topic_data->history.depth, g_pol_history.depth); - CU_ASSERT_EQUAL_FATAL(topic_data->resource_limits.max_samples, g_pol_resource_limits.max_samples); - CU_ASSERT_EQUAL_FATAL(topic_data->resource_limits.max_instances, g_pol_resource_limits.max_instances); - CU_ASSERT_EQUAL_FATAL(topic_data->resource_limits.max_samples_per_instance, g_pol_resource_limits.max_samples_per_instance); - CU_ASSERT_EQUAL_FATAL(topic_data->ownership.kind, g_pol_ownership.kind); - CU_ASSERT_STRING_EQUAL_FATAL(topic_data->topic_data.value._buffer, g_pol_topicdata.value._buffer); - CU_ASSERT_EQUAL_FATAL(topic_data->topic_data.value._length, g_pol_topicdata.value._length); -#endif - DDS_TopicBuiltinTopicData_free(topic_samples[0], DDS_FREE_ALL); -} diff --git a/src/core/ddsi/CMakeLists.txt b/src/core/ddsi/CMakeLists.txt index cf0f7b1..75d3af7 100644 --- a/src/core/ddsi/CMakeLists.txt +++ b/src/core/ddsi/CMakeLists.txt @@ -31,7 +31,6 @@ PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src" q_bitset_inlines.c q_bswap.c q_bswap_inlines.c - q_builtin_topic.c q_config.c q_ddsi_discovery.c q_debmon.c @@ -88,7 +87,6 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/ddsi" q_bitset_template.h q_bswap.h q_bswap_template.h - q_builtin_topic.h q_config.h q_ddsi_discovery.h q_debmon.h diff --git a/src/core/ddsi/include/ddsi/q_builtin_topic.h b/src/core/ddsi/include/ddsi/q_builtin_topic.h deleted file mode 100644 index 47175d2..0000000 --- a/src/core/ddsi/include/ddsi/q_builtin_topic.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License - * v. 1.0 which is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause - */ -#ifndef Q_BUILTIN_TOPIC_H -#define Q_BUILTIN_TOPIC_H - -#include "ddsi/q_time.h" - -#include "dds_builtinTopics.h" - -struct entity_common; -struct nn_plist; - -/* Functions called at proxy entity creation/deletion time, so they - can do whatever is necessary to get the builtin topics function - correctly. - - These probably should return an error code, but I don't quite know - how to handle it yet and this way we have Coverity on our side. - Implementation is outside the common core. - - These may assume the proxy entities are stable, without parallel QoS - changes. */ - -void -propagate_builtin_topic_participant( - _In_ const struct entity_common *proxypp, - _In_ const nn_plist_t *plist, - _In_ nn_wctime_t timestamp, - _In_ int alive); - -void -propagate_builtin_topic_cmparticipant( - _In_ const struct entity_common *proxypp, - _In_ const nn_plist_t *plist, - _In_ nn_wctime_t timestamp, - _In_ int alive); -#if 0 -void dispose_builtin_topic_proxy_participant (const struct proxy_participant *proxypp, nn_wctime_t timestamp, int isimplicit); -void write_builtin_topic_proxy_writer (const struct proxy_writer *pwr, nn_wctime_t timestamp); -void dispose_builtin_topic_proxy_writer (const struct proxy_writer *pwr, nn_wctime_t timestamp, int isimplicit); -void write_builtin_topic_proxy_reader (const struct proxy_reader *prd, nn_wctime_t timestamp); -void dispose_builtin_topic_proxy_reader (const struct proxy_reader *prd, nn_wctime_t timestamp, int isimplicit); -void write_builtin_topic_proxy_group (const struct proxy_group *pgroup, nn_wctime_t timestamp); -void dispose_builtin_topic_proxy_group (const struct proxy_group *pgroup, nn_wctime_t timestamp, int isimplicit); - -void write_builtin_topic_proxy_topic (const struct nn_plist *datap, nn_wctime_t timestamp); -#endif - - -/* - * Let the layer on top of DDSI handle the received builtin data when it wants to. - */ -extern void -forward_builtin_participant( - _In_ DDS_ParticipantBuiltinTopicData *data, - _In_ nn_wctime_t timestamp, - _In_ int alive); - -extern void -forward_builtin_cmparticipant( - _In_ DDS_CMParticipantBuiltinTopicData *data, - _In_ nn_wctime_t timestamp, - _In_ int alive); - - -#endif diff --git a/src/core/ddsi/include/ddsi/q_config.h b/src/core/ddsi/include/ddsi/q_config.h index 30989b1..5c4f8d5 100644 --- a/src/core/ddsi/include/ddsi/q_config.h +++ b/src/core/ddsi/include/ddsi/q_config.h @@ -22,6 +22,7 @@ #include "ddsi/q_xqos.h" #include "ddsi/ddsi_tran.h" #include "ddsi/q_feature_check.h" +#include "ddsi/ddsi_serdata_builtin.h" #include "ddsi/ddsi_rhc_plugin.h" #if defined (__cplusplus) @@ -411,6 +412,7 @@ struct ddsi_plugin { int (*init_fn) (void); void (*fini_fn) (void); + void (*builtin_write) (enum ddsi_sertopic_builtin_type type, const nn_guid_t *guid, nn_wctime_t timestamp, bool alive); /* Read cache */ struct ddsi_rhc_plugin rhc_plugin; diff --git a/src/core/ddsi/include/ddsi/q_globals.h b/src/core/ddsi/include/ddsi/q_globals.h index 7c19652..c91a029 100644 --- a/src/core/ddsi/include/ddsi/q_globals.h +++ b/src/core/ddsi/include/ddsi/q_globals.h @@ -281,6 +281,11 @@ struct q_globals { struct ddsi_sertopic *plist_topic; /* used for all discovery data */ struct ddsi_sertopic *rawcdr_topic; /* used for participant message data */ + /* Sertopics for built-in topics -- FIXME: these really have little to do with topics, but everything with topic types, in other words, they are the type supports in DDS ... so a bit of refactoring is required */ + struct ddsi_sertopic *builtin_participant_topic; + struct ddsi_sertopic *builtin_reader_topic; + struct ddsi_sertopic *builtin_writer_topic; + /* Network ID needed by v_groupWrite -- FIXME: might as well pass it to the receive thread instead of making it global (and that would remove the need to include kernelModule.h) */ diff --git a/src/core/ddsi/src/q_builtin_topic.c b/src/core/ddsi/src/q_builtin_topic.c deleted file mode 100644 index 03119d8..0000000 --- a/src/core/ddsi/src/q_builtin_topic.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License - * v. 1.0 which is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause - */ -#include -#include - -#include "ddsi/q_misc.h" -#include "ddsi/q_config.h" -#include "ddsi/q_entity.h" -#include "ddsi/q_builtin_topic.h" - -#include "dds_builtinTopics.h" - -static void generate_user_data (_Out_ DDS_UserDataQosPolicy *a, _In_ const nn_xqos_t *xqos) -{ - if (!(xqos->present & QP_USER_DATA) || (xqos->user_data.length == 0)) - { - a->value._maximum = 0; - a->value._length = 0; - a->value._buffer = NULL; - a->value._release = false; - } else { - a->value._maximum = xqos->user_data.length; - a->value._length = xqos->user_data.length; - a->value._buffer = xqos->user_data.value; - a->value._release = false; - } -} - -static void -generate_product_data( - _Out_ DDS_ProductDataQosPolicy *a, - _In_ const struct entity_common *participant, - _In_ const nn_plist_t *plist) -{ - /* replicate format generated in v_builtinCreateCMParticipantInfo() */ - static const char product_tag[] = "Product"; - static const char exec_name_tag[] = "ExecName"; - static const char participant_name_tag[] = "ParticipantName"; - static const char process_id_tag[] = "PID"; - static const char node_name_tag[] = "NodeName"; - static const char federation_id_tag[] = "FederationId"; - static const char vendor_id_tag[] = "VendorId"; - static const char service_type_tag[] = "ServiceType"; - const size_t cdata_overhead = 12; /* */ - const size_t tag_overhead = 5; /* <> and */ - char pidstr[11]; /* unsigned 32-bits, so max < 5e9, or 10 chars + terminator */ - char federationidstr[20]; /* max 2 * unsigned 32-bits hex + separator, terminator */ - char vendoridstr[22]; /* max 2 * unsigned 32-bits + seperator, terminator */ - char servicetypestr[11]; /* unsigned 32-bits */ - unsigned servicetype; - size_t len = 1 + 2*(sizeof(product_tag)-1) + tag_overhead; - - if (plist->present & PP_PRISMTECH_EXEC_NAME) - len += 2*(sizeof(exec_name_tag)-1) + cdata_overhead + tag_overhead + strlen(plist->exec_name); - if (plist->present & PP_ENTITY_NAME) - len += 2*(sizeof(participant_name_tag)-1) + cdata_overhead + tag_overhead + strlen(plist->entity_name); - if (plist->present & PP_PRISMTECH_PROCESS_ID) - { - int n = snprintf (pidstr, sizeof (pidstr), "%u", plist->process_id); - assert (n > 0 && (size_t) n < sizeof (pidstr)); - len += 2*(sizeof(process_id_tag)-1) + tag_overhead + (size_t) n; - } - if (plist->present & PP_PRISMTECH_NODE_NAME) - len += 2*(sizeof(node_name_tag)-1) + cdata_overhead + tag_overhead + strlen(plist->node_name); - - { - int n = snprintf (vendoridstr, sizeof (vendoridstr), "%u.%u", plist->vendorid.id[0], plist->vendorid.id[1]); - assert (n > 0 && (size_t) n < sizeof (vendoridstr)); - len += 2*(sizeof(vendor_id_tag)-1) + tag_overhead + (size_t) n; - } - - { - int n; - if (vendor_is_opensplice (plist->vendorid)) - n = snprintf (federationidstr, sizeof (federationidstr), "%x", participant->guid.prefix.u[0]); - else - n = snprintf (federationidstr, sizeof (federationidstr), "%x:%x", participant->guid.prefix.u[0], participant->guid.prefix.u[1]); - assert (n > 0 && (size_t) n < sizeof (federationidstr)); - len += 2*(sizeof(federation_id_tag)-1) + tag_overhead + (size_t) n; - } - - if (plist->present & PP_PRISMTECH_SERVICE_TYPE) - servicetype = plist->service_type; - else - servicetype = 0; - - { - int n = snprintf (servicetypestr, sizeof (servicetypestr), "%u", (unsigned) servicetype); - assert (n > 0 && (size_t) n < sizeof (servicetypestr)); - len += 2*(sizeof(service_type_tag)-1) + tag_overhead + (size_t) n; - } - - a->value = os_malloc(len); - - { - char *p = a->value; - int n; - n = snprintf (p, len, "<%s>", product_tag); assert (n >= 0 && (size_t) n < len); p += n; len -= (size_t) n; - if (plist->present & PP_PRISMTECH_EXEC_NAME) - { - n = snprintf (p, len, "<%s>", exec_name_tag, plist->exec_name, exec_name_tag); - assert (n >= 0 && (size_t) n < len); - p += n; len -= (size_t) n; - } - if (plist->present & PP_ENTITY_NAME) - { - n = snprintf (p, len, "<%s>", participant_name_tag, plist->entity_name, participant_name_tag); - assert (n >= 0 && (size_t) n < len); - p += n; len -= (size_t) n; - } - if (plist->present & PP_PRISMTECH_PROCESS_ID) - { - n = snprintf (p, len, "<%s>%s", process_id_tag, pidstr, process_id_tag); - assert (n >= 0 && (size_t) n < len); - p += n; len -= (size_t) n; - } - if (plist->present & PP_PRISMTECH_NODE_NAME) - { - n = snprintf (p, len, "<%s>", node_name_tag, plist->node_name, node_name_tag); - assert (n >= 0 && (size_t) n < len); - p += n; len -= (size_t) n; - } - n = snprintf (p, len, "<%s>%s", federation_id_tag, federationidstr, federation_id_tag); - assert (n >= 0 && (size_t) n < len); - p += n; len -= (size_t) n; - n = snprintf (p, len, "<%s>%s", vendor_id_tag, vendoridstr, vendor_id_tag); - assert (n >= 0 && (size_t) n < len); - p += n; len -= (size_t) n; - - { - n = snprintf (p, len, "<%s>%s", service_type_tag, servicetypestr, service_type_tag); - assert (n >= 0 && (size_t) n < len); - p += n; len -= (size_t) n; - } - - n = snprintf (p, len, "", product_tag); - assert (n >= 0 && (size_t) n == len-1); - (void) n; - } -} - -static void generate_key (_Out_ DDS_BuiltinTopicKey_t *a, _In_ const nn_guid_prefix_t *gid) -{ - (*a)[0] = gid->u[0]; - (*a)[1] = gid->u[1]; - (*a)[2] = gid->u[2]; -} - -void -propagate_builtin_topic_participant( - _In_ const struct entity_common *participant, - _In_ const nn_plist_t *plist, - _In_ nn_wctime_t timestamp, - _In_ int alive) -{ - DDS_ParticipantBuiltinTopicData data; - generate_key(&(data.key), &(participant->guid.prefix)); - generate_user_data(&(data.user_data), &(plist->qos)); - forward_builtin_participant(&data, timestamp, alive); -} - -void -propagate_builtin_topic_cmparticipant( - _In_ const struct entity_common *participant, - _In_ const nn_plist_t *plist, - _In_ nn_wctime_t timestamp, - _In_ int alive) -{ - DDS_CMParticipantBuiltinTopicData data; - generate_key(&(data.key), &(participant->guid.prefix)); - generate_product_data(&(data.product), participant, plist); - forward_builtin_cmparticipant(&data, timestamp, alive); - os_free(data.product.value); -} diff --git a/src/core/ddsi/src/q_ddsi_discovery.c b/src/core/ddsi/src/q_ddsi_discovery.c index c6fe9f7..0b811d5 100644 --- a/src/core/ddsi/src/q_ddsi_discovery.c +++ b/src/core/ddsi/src/q_ddsi_discovery.c @@ -37,7 +37,6 @@ #include "ddsi/q_transmit.h" #include "ddsi/q_lease.h" #include "ddsi/q_error.h" -#include "ddsi/q_builtin_topic.h" #include "ddsi/ddsi_serdata_default.h" #include "ddsi/q_md5.h" #include "ddsi/q_feature_check.h" @@ -200,8 +199,6 @@ int spdp_write (struct participant *pp) return 0; } - propagate_builtin_topic_participant(&(pp->e), pp->plist, now(), true); - DDS_TRACE("spdp_write(%x:%x:%x:%x)\n", PGUID (pp->e.guid)); if ((wr = get_builtin_writer (pp, NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)) == NULL) @@ -1425,8 +1422,6 @@ int sedp_write_cm_participant (struct participant *pp, int alive) return 0; } - propagate_builtin_topic_cmparticipant(&(pp->e), pp->plist, now(), alive); - sedp_wr = get_sedp_writer (pp, NN_ENTITYID_SEDP_BUILTIN_CM_PARTICIPANT_WRITER); /* The message is only a temporary thing, used only for encoding diff --git a/src/core/ddsi/src/q_entity.c b/src/core/ddsi/src/q_entity.c index 83d2277..1ca70c5 100644 --- a/src/core/ddsi/src/q_entity.c +++ b/src/core/ddsi/src/q_entity.c @@ -35,7 +35,6 @@ #include "ddsi/q_protocol.h" /* NN_ENTITYID_... */ #include "ddsi/q_unused.h" #include "ddsi/q_error.h" -#include "ddsi/q_builtin_topic.h" #include "ddsi/ddsi_serdata_default.h" #include "ddsi/ddsi_mcgroup.h" #include "ddsi/q_receive.h" @@ -155,14 +154,30 @@ static int is_builtin_endpoint (nn_entityid_t id, nn_vendorid_t vendorid) return is_builtin_entityid (id, vendorid) && id.u != NN_ENTITYID_PARTICIPANT; } -static void entity_common_init (struct entity_common *e, const struct nn_guid *guid, const char *name, enum entity_kind kind, bool onlylocal) +static void entity_common_init (struct entity_common *e, const struct nn_guid *guid, const char *name, enum entity_kind kind, nn_vendorid_t vendorid, bool onlylocal, struct ddsi_tkmap_instance **tk) { e->guid = *guid; e->kind = kind; e->name = os_strdup (name ? name : ""); - e->iid = ddsi_iid_gen (); - os_mutexInit (&e->lock); e->onlylocal = onlylocal; + os_mutexInit (&e->lock); + if (onlylocal || is_builtin_entityid (guid->entityid, vendorid)) + { + e->iid = ddsi_iid_gen (); + *tk = NULL; + } + else + { + struct ddsi_serdata *sd; + struct nn_keyhash kh; + memcpy (&kh, guid, sizeof (kh)); + /* any random builtin topic will do (provided it has a GUID for a key), because what matters is the "class" of the topic, not the actual topic; also, this is called early in the initialisation of the entity with this GUID, which simply causes serdata_from_keyhash to create a key-only serdata because the key lookup fails. */ + sd = ddsi_serdata_from_keyhash (gv.builtin_participant_topic, &kh); + /* FIXME: this makes the iid for a reincarnation of a proxy entity dependent on whether an application reader kept the corresponding built-in topic instance around, it may be attractive to reconsider and guarantee a new iid in these cases, at least for the publication handle */ + *tk = ddsi_tkmap_find(sd, false, true); + ddsi_serdata_unref (sd); + e->iid = (*tk)->m_iid; + } } static void entity_common_fini (struct entity_common *e) @@ -223,6 +238,36 @@ void local_reader_ary_setinvalid (struct local_reader_ary *x) os_mutexUnlock (&x->rdary_lock); } +static void write_builtin_topic_any (const struct entity_common *e, nn_wctime_t timestamp, bool alive, nn_vendorid_t vendorid, struct ddsi_tkmap_instance *tk) +{ + enum ddsi_sertopic_builtin_type type; + switch (e->kind) + { + case EK_PARTICIPANT: + case EK_PROXY_PARTICIPANT: + type = DSBT_PARTICIPANT; + break; + case EK_READER: + case EK_PROXY_READER: + type = DSBT_READER; + break; + case EK_WRITER: + case EK_PROXY_WRITER: + type = DSBT_WRITER; + break; + } + if (!(e->onlylocal || is_builtin_endpoint(e->guid.entityid, vendorid))) + ddsi_plugin.builtin_write (type, &e->guid, timestamp, alive); + /* tkmap instance only needs to be kept around until the first write of a built-in topic (if none ever happens, it needn't be kept at all): afterward, the WHC of the local built-in topic writer will keep the entry alive. FIXME: the SPDP/SEPD ones currently use default sertopics instead of builtin sertopics, and so use different mappings and different instnace ids. No-one ever sees those ids, so it doesn't matter, but it would nicer if it could actually be the same one. FIXME: it would also be nicer if the local built-in topics and the SPDP/SEDP writers were the same, but I want the locally created endpoints visible in the built-in topics as well, and those don't exist in the discovery writers ... */ + if (tk) + ddsi_tkmap_instance_unref (tk); +} + +static void write_builtin_topic_local (const struct entity_common *e, nn_wctime_t timestamp, bool alive, struct ddsi_tkmap_instance *tk) +{ + write_builtin_topic_any(e, timestamp, alive, ownvendorid, tk); +} + /* DELETED PARTICIPANTS --------------------------------------------- */ int deleted_participants_admin_init (void) @@ -359,6 +404,7 @@ int new_participant_guid (const nn_guid_t *ppguid, unsigned flags, const nn_plis { struct participant *pp; nn_guid_t subguid, group_guid; + struct ddsi_tkmap_instance *tk; /* no reserved bits may be set */ assert ((flags & ~(RTPS_PF_NO_BUILTIN_READERS | RTPS_PF_NO_BUILTIN_WRITERS | RTPS_PF_PRIVILEGED_PP | RTPS_PF_IS_DDSI2_PP | RTPS_PF_ONLY_LOCAL)) == 0); @@ -401,7 +447,7 @@ int new_participant_guid (const nn_guid_t *ppguid, unsigned flags, const nn_plis pp = os_malloc (sizeof (*pp)); - entity_common_init (&pp->e, ppguid, "", EK_PARTICIPANT, ((flags & RTPS_PF_ONLY_LOCAL) != 0)); + entity_common_init (&pp->e, ppguid, "", EK_PARTICIPANT, ownvendorid, ((flags & RTPS_PF_ONLY_LOCAL) != 0), &tk); pp->user_refc = 1; pp->builtin_refc = 0; pp->builtins_deleted = 0; @@ -580,6 +626,8 @@ int new_participant_guid (const nn_guid_t *ppguid, unsigned flags, const nn_plis trigger_recv_threads (); } + write_builtin_topic_local(&pp->e, now(), true, tk); + /* SPDP periodic broadcast uses the retransmit path, so the initial publication must be done differently. Must be later than making the participant globally visible, or the SPDP processing won't @@ -606,7 +654,6 @@ int new_participant_guid (const nn_guid_t *ppguid, unsigned flags, const nn_plis tsched.v = (pp->lease_duration == T_NEVER) ? T_NEVER : 0; pp->pmd_update_xevent = qxev_pmd_update (tsched, &pp->e.guid); } - return 0; } @@ -815,11 +862,7 @@ int delete_participant (const struct nn_guid *ppguid) struct participant *pp; if ((pp = ephash_lookup_participant_guid (ppguid)) == NULL) return ERR_UNKNOWN_ENTITY; - if (!(pp->e.onlylocal)) - { - propagate_builtin_topic_cmparticipant(&(pp->e), pp->plist, now(), false); - propagate_builtin_topic_participant(&(pp->e), pp->plist, now(), false); - } + write_builtin_topic_local(&pp->e, now(), false, NULL); remember_deleted_participant_guid (&pp->e.guid); ephash_remove_participant_guid (pp); gcreq_participant (pp); @@ -2333,10 +2376,11 @@ static void endpoint_common_init enum entity_kind kind, const struct nn_guid *guid, const struct nn_guid *group_guid, - struct participant *pp + struct participant *pp, + struct ddsi_tkmap_instance **tk ) { - entity_common_init (e, guid, NULL, kind, pp->e.onlylocal); + entity_common_init (e, guid, NULL, kind, ownvendorid, pp->e.onlylocal, tk); c->pp = ref_participant (pp, &e->guid); if (group_guid) { @@ -2563,6 +2607,7 @@ static struct writer * new_writer_guid (const struct nn_guid *guid, const struct { struct writer *wr; nn_mtime_t tnow = now_mt (); + struct ddsi_tkmap_instance *tk; assert (is_writer_entityid (guid->entityid)); assert (ephash_lookup_writer_guid (guid) == NULL); @@ -2575,7 +2620,7 @@ static struct writer * new_writer_guid (const struct nn_guid *guid, const struct delete_participant won't interfere with our ability to address the participant */ - endpoint_common_init (&wr->e, &wr->c, EK_WRITER, guid, group_guid, pp); + endpoint_common_init (&wr->e, &wr->c, EK_WRITER, guid, group_guid, pp, &tk); os_condInit (&wr->throttle_cond, &wr->e.lock); wr->seq = 0; @@ -2784,6 +2829,7 @@ static struct writer * new_writer_guid (const struct nn_guid *guid, const struct deleted while we do so */ match_writer_with_proxy_readers (wr, tnow); match_writer_with_local_readers (wr, tnow); + write_builtin_topic_local(&wr->e, now(), true, tk); sedp_write_writer (wr); if (wr->lease_duration != T_NEVER) @@ -2909,6 +2955,7 @@ int delete_writer_nolinger_locked (struct writer *wr) { DDS_LOG(DDS_LC_DISCOVERY, "delete_writer_nolinger(guid %x:%x:%x:%x) ...\n", PGUID (wr->e.guid)); ASSERT_MUTEX_HELD (&wr->e.lock); + write_builtin_topic_local(&wr->e, now(), false, NULL); local_reader_ary_setinvalid (&wr->rdary); ephash_remove_writer_guid (wr); writer_set_state (wr, WRST_DELETING); @@ -3125,6 +3172,7 @@ static struct reader * new_reader_guid struct reader * rd; nn_mtime_t tnow = now_mt (); + struct ddsi_tkmap_instance *tk; assert (!is_writer_entityid (guid->entityid)); assert (ephash_lookup_reader_guid (guid) == NULL); @@ -3133,7 +3181,7 @@ static struct reader * new_reader_guid new_reader_writer_common (guid, topic, xqos); rd = os_malloc (sizeof (*rd)); - endpoint_common_init (&rd->e, &rd->c, EK_READER, guid, group_guid, pp); + endpoint_common_init (&rd->e, &rd->c, EK_READER, guid, group_guid, pp, &tk); /* Copy QoS, merging in defaults */ rd->xqos = os_malloc (sizeof (*rd->xqos)); @@ -3237,6 +3285,7 @@ static struct reader * new_reader_guid ephash_insert_reader_guid (rd); match_reader_with_proxy_writers (rd, tnow); match_reader_with_local_writers (rd, tnow); + write_builtin_topic_local(&rd->e, now(), true, tk); sedp_write_reader (rd); return rd; } @@ -3329,6 +3378,7 @@ int delete_reader (const struct nn_guid *guid) (ddsi_plugin.rhc_plugin.rhc_fini_fn) (rd->rhc); } DDS_LOG(DDS_LC_DISCOVERY, "delete_reader_guid(guid %x:%x:%x:%x) ...\n", PGUID (*guid)); + write_builtin_topic_local(&rd->e, now(), false, NULL); ephash_remove_reader_guid (rd); gcreq_reader (rd); return 0; @@ -3404,6 +3454,7 @@ void new_proxy_participant runs on a single thread, it can't go wrong. FIXME, maybe? The same holds for the other functions for creating entities. */ struct proxy_participant *proxypp; + struct ddsi_tkmap_instance *tk; assert (ppguid->entityid.u == NN_ENTITYID_PARTICIPANT); assert (ephash_lookup_proxy_participant_guid (ppguid) == NULL); @@ -3413,7 +3464,7 @@ void new_proxy_participant proxypp = os_malloc (sizeof (*proxypp)); - entity_common_init (&proxypp->e, ppguid, "", EK_PROXY_PARTICIPANT, false); + entity_common_init (&proxypp->e, ppguid, "", EK_PROXY_PARTICIPANT, vendor, false, &tk); proxypp->refc = 1; proxypp->lease_expired = 0; proxypp->vendor = vendor; @@ -3569,15 +3620,7 @@ void new_proxy_participant if (proxypp->owns_lease) lease_register (os_atomic_ldvoidp (&proxypp->lease)); - if (proxypp->proxypp_have_spdp) - { - propagate_builtin_topic_participant(&(proxypp->e), proxypp->plist, timestamp, true); - if (proxypp->proxypp_have_cm) - { - propagate_builtin_topic_cmparticipant(&(proxypp->e), proxypp->plist, timestamp, true); - } - } - + write_builtin_topic_any(&proxypp->e, timestamp, true, proxypp->vendor, tk); os_mutexUnlock (&proxypp->e.lock); } @@ -3595,14 +3638,10 @@ int update_proxy_participant_plist_locked (struct proxy_participant *proxypp, co switch (source) { case UPD_PROXYPP_SPDP: - propagate_builtin_topic_participant(&(proxypp->e), proxypp->plist, timestamp, true); - if (!proxypp->proxypp_have_spdp && proxypp->proxypp_have_cm) - propagate_builtin_topic_cmparticipant(&(proxypp->e), proxypp->plist, timestamp, true); + write_builtin_topic_any(&proxypp->e, timestamp, true, proxypp->vendor, NULL); proxypp->proxypp_have_spdp = 1; break; case UPD_PROXYPP_CM: - if (proxypp->proxypp_have_spdp) - propagate_builtin_topic_cmparticipant(&(proxypp->e), proxypp->plist, timestamp, true); proxypp->proxypp_have_cm = 1; break; } @@ -3848,8 +3887,7 @@ int delete_proxy_participant_by_guid (const struct nn_guid * guid, nn_wctime_t t return ERR_UNKNOWN_ENTITY; } DDS_LOG(DDS_LC_DISCOVERY, "- deleting\n"); - propagate_builtin_topic_cmparticipant(&(ppt->e), ppt->plist, timestamp, false); - propagate_builtin_topic_participant(&(ppt->e), ppt->plist, timestamp, false); + write_builtin_topic_any(&ppt->e, timestamp, false, ppt->vendor, NULL); remember_deleted_participant_guid (&ppt->e.guid); ephash_remove_proxy_participant_guid (ppt); os_mutexUnlock (&gv.lock); @@ -3982,7 +4020,7 @@ static void proxy_endpoint_common_init ( struct entity_common *e, struct proxy_endpoint_common *c, enum entity_kind kind, const struct nn_guid *guid, struct proxy_participant *proxypp, - struct addrset *as, const nn_plist_t *plist + struct addrset *as, const nn_plist_t *plist, struct ddsi_tkmap_instance **tk ) { const char *name; @@ -3993,7 +4031,7 @@ static void proxy_endpoint_common_init assert ((plist->qos.present & (QP_TOPIC_NAME | QP_TYPE_NAME)) == (QP_TOPIC_NAME | QP_TYPE_NAME)); name = (plist->present & PP_ENTITY_NAME) ? plist->entity_name : ""; - entity_common_init (e, guid, name, kind, false); + entity_common_init (e, guid, name, kind, proxypp->vendor, false, tk); c->xqos = nn_xqos_dup (&plist->qos); c->as = ref_addrset (as); c->topic = NULL; /* set from first matching reader/writer */ @@ -4027,6 +4065,7 @@ int new_proxy_writer (const struct nn_guid *ppguid, const struct nn_guid *guid, struct proxy_writer *pwr; int isreliable; nn_mtime_t tnow = now_mt (); + struct ddsi_tkmap_instance *tk; (void)timestamp; assert (is_writer_entityid (guid->entityid)); assert (ephash_lookup_proxy_writer_guid (guid) == NULL); @@ -4038,7 +4077,7 @@ int new_proxy_writer (const struct nn_guid *ppguid, const struct nn_guid *guid, } pwr = os_malloc (sizeof (*pwr)); - proxy_endpoint_common_init (&pwr->e, &pwr->c, EK_PROXY_WRITER, guid, proxypp, as, plist); + proxy_endpoint_common_init (&pwr->e, &pwr->c, EK_PROXY_WRITER, guid, proxypp, as, plist, &tk); ut_avlInit (&pwr_readers_treedef, &pwr->readers); pwr->n_reliable_readers = 0; @@ -4104,6 +4143,7 @@ int new_proxy_writer (const struct nn_guid *ppguid, const struct nn_guid *guid, local_reader_ary_init (&pwr->rdary); ephash_insert_proxy_writer_guid (pwr); match_proxy_writer_with_readers (pwr, tnow); + write_builtin_topic_any(&pwr->e, timestamp, true, pwr->c.vendor, tk); os_mutexLock (&pwr->e.lock); pwr->local_matching_inprogress = 0; @@ -4235,6 +4275,7 @@ int delete_proxy_writer (const struct nn_guid *guid, nn_wctime_t timestamp, int from removing themselves from the proxy writer's rdary[]. */ local_reader_ary_setinvalid (&pwr->rdary); DDS_LOG(DDS_LC_DISCOVERY, "- deleting\n"); + write_builtin_topic_any(&pwr->e, timestamp, false, pwr->c.vendor, NULL); ephash_remove_proxy_writer_guid (pwr); os_mutexUnlock (&gv.lock); gcreq_proxy_writer (pwr); @@ -4252,6 +4293,7 @@ int new_proxy_reader (const struct nn_guid *ppguid, const struct nn_guid *guid, struct proxy_participant *proxypp; struct proxy_reader *prd; nn_mtime_t tnow = now_mt (); + struct ddsi_tkmap_instance *tk; (void)timestamp; assert (!is_writer_entityid (guid->entityid)); @@ -4264,7 +4306,7 @@ int new_proxy_reader (const struct nn_guid *ppguid, const struct nn_guid *guid, } prd = os_malloc (sizeof (*prd)); - proxy_endpoint_common_init (&prd->e, &prd->c, EK_PROXY_READER, guid, proxypp, as, plist); + proxy_endpoint_common_init (&prd->e, &prd->c, EK_PROXY_READER, guid, proxypp, as, plist, &tk); prd->deleting = 0; #ifdef DDSI_INCLUDE_SSM @@ -4278,6 +4320,7 @@ int new_proxy_reader (const struct nn_guid *ppguid, const struct nn_guid *guid, ut_avlInit (&prd_writers_treedef, &prd->writers); ephash_insert_proxy_reader_guid (prd); match_proxy_reader_with_writers (prd, tnow); + write_builtin_topic_any(&prd->e, timestamp, true, prd->c.vendor, tk); return 0; } @@ -4360,6 +4403,7 @@ int delete_proxy_reader (const struct nn_guid *guid, nn_wctime_t timestamp, int DDS_LOG(DDS_LC_DISCOVERY, "- unknown\n"); return ERR_UNKNOWN_ENTITY; } + write_builtin_topic_any(&prd->e, timestamp, false, prd->c.vendor, NULL); ephash_remove_proxy_reader_guid (prd); os_mutexUnlock (&gv.lock); DDS_LOG(DDS_LC_DISCOVERY, "- deleting\n"); diff --git a/src/core/ddsi/src/q_init.c b/src/core/ddsi/src/q_init.c index 8239391..374ad8e 100644 --- a/src/core/ddsi/src/q_init.c +++ b/src/core/ddsi/src/q_init.c @@ -56,6 +56,7 @@ #include "ddsi/ddsi_raweth.h" #include "ddsi/ddsi_mcgroup.h" #include "ddsi/ddsi_serdata_default.h" +#include "ddsi/ddsi_serdata_builtin.h" #include "ddsi/ddsi_tkmap.h" #include "dds__whc.h" @@ -783,12 +784,18 @@ static void make_special_topics (void) { gv.plist_topic = make_special_topic (PLATFORM_IS_LITTLE_ENDIAN ? PL_CDR_LE : PL_CDR_BE, &ddsi_serdata_ops_plist); gv.rawcdr_topic = make_special_topic (PLATFORM_IS_LITTLE_ENDIAN ? CDR_LE : CDR_BE, &ddsi_serdata_ops_rawcdr); + gv.builtin_participant_topic = new_sertopic_builtin (DSBT_PARTICIPANT, "DCPSParticipant", "org::eclipse::cyclonedds::builtin::DCPSParticipant"); + gv.builtin_reader_topic = new_sertopic_builtin (DSBT_READER, "DCPSSubscription", "org::eclipse::cyclonedds::builtin::DCPSSubscription"); + gv.builtin_writer_topic = new_sertopic_builtin (DSBT_WRITER, "DCPSPublication", "org::eclipse::cyclonedds::builtin::DCPSPublication"); } static void free_special_topics (void) { ddsi_sertopic_unref (gv.plist_topic); ddsi_sertopic_unref (gv.rawcdr_topic); + ddsi_sertopic_unref (gv.builtin_participant_topic); + ddsi_sertopic_unref (gv.builtin_reader_topic); + ddsi_sertopic_unref (gv.builtin_writer_topic); } static int setup_and_start_recv_threads (void) diff --git a/src/tools/ddsls/ddsls.c b/src/tools/ddsls/ddsls.c index a117ecf..40cb1a3 100644 --- a/src/tools/ddsls/ddsls.c +++ b/src/tools/ddsls/ddsls.c @@ -11,836 +11,570 @@ */ #include "os/os.h" #include "ddsc/dds.h" -#include "dds_builtinTopics.h" - - -#define DURATION_INFINITE_SEC 0x7fffffff -#define DURATION_INFINITE_NSEC 0x7fffffff -#define zero(pp,sz) _zero((void**)pp,sz) // FIXME Temporary workaround for lack of wait_for_historical implementation. Remove this on completion of CHAM-268. #define dds_reader_wait_for_historical_data(a,b) DDS_SUCCESS; dds_sleepfor(DDS_MSECS(200)); -/* Enable DEBUG for printing debug statements*/ -//#define DEBUG +// FIXME should fix read/take interface to allow simple unlimited take +#define MAX_SAMPLES 10 -#ifdef DEBUG -#define PRINTD printf -#else -#define PRINTD(...) +#define MAX_DURATION_BUFSZ 21 +char *qp_duration_str (char *buf, size_t bufsz, dds_duration_t d) +{ + if (d == DDS_INFINITY) + snprintf (buf, bufsz, "infinite"); + else + snprintf (buf, bufsz, "%u.%09u", (unsigned)(d / DDS_NSECS_IN_SEC), (unsigned)(d % DDS_NSECS_IN_SEC)); + return buf; +} + +size_t printable_seq_length (const unsigned char *as, size_t n) +{ + size_t i; + for (i = 0; i < n; i++) { + if (as[i] < 32 || as[i] >= 127) + break; + } + return i; +} + +void print_octetseq (const unsigned char *v, size_t sz, FILE *fp) +{ + size_t i, n; + fprintf (fp, "%zu<", sz); + i = 0; + while (i < sz) + { + if ((n = printable_seq_length (v + i, sz - i)) < 4) + { + if (n == 0) + n = 1; + while (n--) + { + fprintf (fp, "%s%u", i == 0 ? "" : ",", v[i]); + i++; + } + } + else + { + fprintf (fp, "\"%*.*s\"", (int)n, (int)n, v + i); + i += n; + } + } + fprintf (fp, ">"); +} + +void qp_user_data (const dds_qos_t *q, FILE *fp) +{ + void *ud; + size_t udsz; + if (dds_qget_userdata(q, &ud, &udsz)) + { + fprintf (fp, " user_data: value = "); + print_octetseq (ud, udsz,fp); + fprintf (fp, "\n"); + dds_free (ud); + } +} + +void qp_topic_data (const dds_qos_t *q, FILE *fp) +{ + void *ud; + size_t udsz; + if (dds_qget_topicdata(q, &ud, &udsz)) + { + fprintf (fp, " topic_data: value = "); + print_octetseq (ud, udsz,fp); + fprintf (fp, "\n"); + dds_free (ud); + } +} + +void qp_group_data (const dds_qos_t *q, FILE *fp) +{ + void *ud; + size_t udsz; + if (dds_qget_groupdata(q, &ud, &udsz)) + { + fprintf (fp, " group_data: value = "); + print_octetseq (ud, udsz,fp); + fprintf (fp, "\n"); + dds_free (ud); + } +} + +void qp_durability (const dds_qos_t *q, FILE *fp) +{ + dds_durability_kind_t kind; + if (dds_qget_durability (q, &kind)) + { + static const char *s = "?"; + switch (kind) + { + case DDS_DURABILITY_VOLATILE: s = "volatile"; break; + case DDS_DURABILITY_TRANSIENT_LOCAL: s = "transient-local"; break; + case DDS_DURABILITY_TRANSIENT: s = "transient"; break; + case DDS_DURABILITY_PERSISTENT: s = "persistent"; break; + } + fprintf (fp, " durability: kind = %s\n", s); + } +} + +void qp_history (const dds_qos_t *q, FILE *fp) +{ + dds_history_kind_t kind; + int32_t depth; + if (dds_qget_history (q, &kind, &depth)) + { + fprintf (fp, " history: kind = "); + switch (kind) + { + case DDS_HISTORY_KEEP_LAST: + fprintf (fp, "keep-last, depth = %"PRId32"\n", depth); + break; + case DDS_HISTORY_KEEP_ALL: + fprintf (fp, "keep-all (depth = %"PRId32")\n", depth); + break; + } + } +} + +void qp_resource_limits_1 (FILE *fp, int32_t max_samples, int32_t max_instances, int32_t max_samples_per_instance, int indent) +{ + fprintf (fp, "%*.*sresource_limits: max_samples = ", indent, indent, ""); + if (max_samples == DDS_LENGTH_UNLIMITED) + fprintf (fp, "unlimited"); + else + fprintf (fp, "%d", max_samples); + fprintf (fp, ", max_instances = "); + if (max_instances == DDS_LENGTH_UNLIMITED) + fprintf (fp, "unlimited"); + else + fprintf (fp, "%d", max_instances); + fprintf (fp, ", max_samples_per_instance = "); + if (max_samples_per_instance == DDS_LENGTH_UNLIMITED) + fprintf (fp, "unlimited\n"); + else + fprintf (fp, "%d\n", max_samples_per_instance); +} + +void qp_resource_limits (const dds_qos_t *q, FILE *fp) +{ + int32_t max_samples, max_instances, max_samples_per_instance; + if (dds_qget_resource_limits (q, &max_samples, &max_instances, &max_samples_per_instance)) + qp_resource_limits_1 (fp, max_samples, max_instances, max_samples_per_instance, 2); +} + +void qp_presentation (const dds_qos_t *q, FILE *fp) +{ + dds_presentation_access_scope_kind_t access_scope; + bool coherent_access, ordered_access; + if (dds_qget_presentation (q, &access_scope, &coherent_access, &ordered_access)) + { + static const char *s = "?"; + switch (access_scope) + { + case DDS_PRESENTATION_INSTANCE: s = "instance"; break; + case DDS_PRESENTATION_TOPIC: s = "topic"; break; + case DDS_PRESENTATION_GROUP: s = "group"; break; + } + fprintf (fp, " presentation: scope = %s, coherent_access = %s, ordered_access = %s\n", s, coherent_access ? "true" : "false", ordered_access ? "true" : "false"); + } +} + +void qp_duration_qos (const dds_qos_t *q, FILE *fp, const char *what, bool (*qget) (const dds_qos_t * __restrict qos, dds_duration_t *d)) +{ + dds_duration_t d; + char buf[MAX_DURATION_BUFSZ]; + if (qget (q, &d)) + fprintf (fp, " %s = %s\n", what, qp_duration_str (buf, sizeof (buf), d)); +} + +void qp_lifespan (const dds_qos_t *q, FILE *fp) +{ + qp_duration_qos (q, fp, "lifespan: duration = ", dds_qget_lifespan); +} + +void qp_deadline (const dds_qos_t *q, FILE *fp) +{ + qp_duration_qos (q, fp, "deadline: period = ", dds_qget_deadline); +} + +void qp_latency_budget (const dds_qos_t *q, FILE *fp) +{ + qp_duration_qos (q, fp, "latency_budget: duration = ", dds_qget_latency_budget); +} + +void qp_time_based_filter (const dds_qos_t *q, FILE *fp) +{ + qp_duration_qos (q, fp, "time_based_filter: minimum_separation = ", dds_qget_time_based_filter); +} + +void qp_ownership (const dds_qos_t *q, FILE *fp) +{ + dds_ownership_kind_t kind; + char *s = "?"; + if (dds_qget_ownership (q, &kind)) + { + switch (kind) + { + case DDS_OWNERSHIP_SHARED: s = "shared"; break; + case DDS_OWNERSHIP_EXCLUSIVE: s = "exclusive"; break; + } + fprintf (fp, " ownership: kind = %s\n", s); + } +} + +void qp_ownership_strength (const dds_qos_t *q, FILE *fp) +{ + int32_t value; + if (dds_qget_ownership_strength (q, &value)) + fprintf (fp, " ownership_strength: value = %"PRId32"\n", value); +} + +void qp_liveliness (const dds_qos_t *q, FILE *fp) +{ + dds_liveliness_kind_t kind; + dds_duration_t lease_duration; + if (dds_qget_liveliness (q, &kind, &lease_duration)) + { + char *s = "?"; + char buf[MAX_DURATION_BUFSZ]; + switch (kind) + { + case DDS_LIVELINESS_AUTOMATIC: s = "automatic"; break; + case DDS_LIVELINESS_MANUAL_BY_PARTICIPANT: s = "manual-by-participant"; break; + case DDS_LIVELINESS_MANUAL_BY_TOPIC: s = "manual-by-topic"; break; + } + fprintf (fp, " liveliness: kind = %s, lease_duration = %s\n", s, qp_duration_str (buf, sizeof (buf), lease_duration)); + } +} + +void qp_reliability (const dds_qos_t *q, FILE *fp) +{ + dds_reliability_kind_t kind; + dds_duration_t max_blocking_time; + if (dds_qget_reliability (q, &kind, &max_blocking_time)) + { + char *s = "?"; + char buf[MAX_DURATION_BUFSZ]; + switch (kind) + { + case DDS_RELIABILITY_BEST_EFFORT: s = "best-effort"; break; + case DDS_RELIABILITY_RELIABLE: s = "reliable"; break; + } + fprintf (fp, " reliability: kind = %s, max_blocking_time = %s\n", s, qp_duration_str (buf, sizeof (buf), max_blocking_time)); + } +} + +void qp_transport_priority (const dds_qos_t *q, FILE *fp) +{ + int32_t value; + if (dds_qget_transport_priority (q, &value)) + fprintf (fp, " transport_priority: priority = %"PRId32"\n", value); +} + +void qp_destination_order (const dds_qos_t *q, FILE *fp) +{ + dds_destination_order_kind_t kind; + if (dds_qget_destination_order (q, &kind)) + { + static const char *s = "?"; + switch (kind) + { + case DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP: s = "by-reception-timestamp"; break; + case DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP: s = "by-source-timestamp"; break; + } + fprintf (fp, " destination_order: kind = %s\n", s); + } +} + +void qp_writer_data_lifecycle (const dds_qos_t *q, FILE *fp) +{ + bool value; + if (dds_qget_writer_data_lifecycle (q, &value)) + fprintf (fp, " writer_data_lifecycle: autodispose_unregistered_instances = %s\n", value ? "true" : "false"); +} + +void qp_reader_data_lifecycle (const dds_qos_t *q, FILE *fp) +{ + dds_duration_t autopurge_nowriter_samples_delay, autopurge_disposed_samples_delay; + if (dds_qget_reader_data_lifecycle (q, &autopurge_nowriter_samples_delay, &autopurge_disposed_samples_delay)) + { + char buf1[MAX_DURATION_BUFSZ], buf2[MAX_DURATION_BUFSZ]; + fprintf (fp, " reader_data_lifecycle: autopurge_nowriter_samples_delay = %s, autopurge_disposed_samples_delay = %s\n", qp_duration_str (buf1, sizeof (buf1), autopurge_nowriter_samples_delay), qp_duration_str (buf2, sizeof (buf2), autopurge_disposed_samples_delay)); + } +} + +void qp_durability_service (const dds_qos_t *q, FILE *fp) +{ + dds_duration_t service_cleanup_delay; + dds_history_kind_t history_kind; + int32_t history_depth; + int32_t max_samples, max_instances, max_samples_per_instance; + if (dds_qget_durability_service (q, &service_cleanup_delay, &history_kind, &history_depth, &max_samples, &max_instances, &max_samples_per_instance)) + { + char buf[MAX_DURATION_BUFSZ]; + fprintf (fp, " durability_service:\n"); + fprintf (fp, " service_cleanup_delay: %s\n", qp_duration_str (buf, sizeof (buf), service_cleanup_delay)); + switch (history_kind) + { + case DDS_HISTORY_KEEP_LAST: + fprintf (fp, " history: kind = keep-last, depth = %"PRId32"\n", history_depth); + break; + case DDS_HISTORY_KEEP_ALL: + fprintf (fp, " history: kind = keep-all (depth = %"PRId32")\n", history_depth); + break; + } + qp_resource_limits_1(fp, max_samples, max_instances, max_samples_per_instance, 4); + } +} + +void qp_partition (const dds_qos_t *q, FILE *fp) +{ + uint32_t n; + char **ps; + if (dds_qget_partition (q, &n, &ps)) + { + fprintf (fp, " partition: name = "); + if (n == 0) + fprintf (fp, "(default)"); + else if (n == 1) + fprintf (fp, "%s", ps[0]); + else + { + fprintf (fp, "{"); + for (uint32_t i = 0; i < n; i++) + fprintf (fp, "%s%s", (i > 0) ? "," : "", ps[i]); + fprintf (fp, "}"); + } + fprintf (fp, "\n"); + for (uint32_t i = 0; i < n; i++) + dds_free (ps[i]); + dds_free (ps); + } +} + +void qp_qos (const dds_qos_t *q, FILE *fp) +{ + qp_reliability (q, fp); + qp_durability (q, fp); + qp_destination_order (q, fp); + qp_partition (q, fp); + qp_history (q, fp); + qp_presentation (q, fp); + qp_resource_limits (q, fp); + qp_deadline (q, fp); + qp_latency_budget (q, fp); + qp_lifespan (q, fp); + qp_liveliness (q, fp); + qp_time_based_filter (q, fp); + qp_transport_priority (q, fp); + qp_writer_data_lifecycle (q, fp); + qp_reader_data_lifecycle (q, fp); + qp_durability_service (q, fp); + qp_ownership (q, fp); + qp_ownership_strength (q, fp); + qp_user_data (q, fp); + qp_topic_data (q, fp); + qp_group_data (q, fp); +} + +void print_key(FILE *fp, const char *label, const dds_builtintopic_guid_t *key) +{ + fprintf(fp, "%s", label); + for(size_t j = 0; j < sizeof (key->v); j++) { + fprintf(fp, "%s%02x", (j == 0) ? " " : ":", key->v[j]); + } + fprintf(fp, "\n"); +} + +#if 0 +void print_dcps_topic (FILE *fp, dds_entity_t pp) +{ + dds_entity_t rd = dds_create_reader (pp, DDS_BUILTIN_TOPIC_DCPSTOPIC, NULL, NULL); + (void)dds_reader_wait_for_historical_data (rd, DDS_SECS (5)); + while(true) + { + void *ptrs[MAX_SAMPLES] = { 0 }; + dds_sample_info_t info[sizeof (ptrs) / sizeof (ptrs[0])]; + int n = dds_take (rd, ptrs, info, sizeof (ptrs) / sizeof (ptrs[0]), sizeof (ptrs) / sizeof (ptrs[0])); + if (n <= 0) + break; + for (int i = 0; i < n; i++) + { + dds_builtintopic_topic_t *data = ptrs[i]; + fprintf (fp,"TOPIC:\n"); + print_key (fp, " key =", &data->key); + if (info[i].valid_data) + { + qp_qos (data->qos, fp); + } + } + dds_return_loan (rd, ptrs, n); + } + dds_delete (rd); +} #endif +void print_dcps_participant (FILE *fp, dds_entity_t pp) +{ + dds_entity_t rd = dds_create_reader (pp, DDS_BUILTIN_TOPIC_DCPSPARTICIPANT, NULL, NULL); + (void)dds_reader_wait_for_historical_data (rd, DDS_SECS (5)); + while(true) + { + void *ptrs[MAX_SAMPLES] = { 0 }; + dds_sample_info_t info[sizeof (ptrs) / sizeof (ptrs[0])]; + int n = dds_take (rd, ptrs, info, sizeof (ptrs) / sizeof (ptrs[0]), sizeof (ptrs) / sizeof (ptrs[0])); + if (n <= 0) + break; + for (int i = 0; i < n; i++) + { + dds_builtintopic_participant_t *data = ptrs[i]; + fprintf (fp,"PARTICIPANT:\n"); + print_key (fp, " key =", &data->key); + if (info[i].valid_data) + { + qp_qos (data->qos, fp); + } + } + dds_return_loan (rd, ptrs, n); + } + dds_delete (rd); +} + +void print_dcps_endpoint (FILE *fp, dds_entity_t pp, const char *type, dds_entity_t topic) +{ + dds_entity_t rd = dds_create_reader (pp, topic, NULL, NULL); + (void)dds_reader_wait_for_historical_data (rd, DDS_SECS (5)); + while(true) + { + void *ptrs[MAX_SAMPLES] = { 0 }; + dds_sample_info_t info[sizeof (ptrs) / sizeof (ptrs[0])]; + int n = dds_take (rd, ptrs, info, sizeof (ptrs) / sizeof (ptrs[0]), sizeof (ptrs) / sizeof (ptrs[0])); + if (n <= 0) + break; + for (int i = 0; i < n; i++) + { + dds_builtintopic_endpoint_t *data = ptrs[i]; + fprintf (fp,"%s:\n", type); + print_key (fp, " key =", &data->key); + if (info[i].valid_data) + { + print_key (fp, " participant_key =", &data->participant_key); + fprintf (fp," topic_name = %s\n", data->topic_name); + fprintf (fp," type_name = %s\n", data->type_name); + qp_qos (data->qos,fp); + } + } + dds_return_loan (rd, ptrs, n); + } + dds_delete (rd); +} + +void print_dcps_subscription (FILE *fp, dds_entity_t pp) +{ + print_dcps_endpoint (fp, pp, "SUBSCRIPTION", DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION); +} + +void print_dcps_publication (FILE *fp, dds_entity_t pp) +{ + print_dcps_endpoint (fp, pp, "PUBLICATION", DDS_BUILTIN_TOPIC_DCPSPUBLICATION); +} + #define DCPSTOPIC_FLAG 1 #define DCPSPARTICIPANT_FLAG (1<<1) #define DCPSSUBSCRIPTION_FLAG (1<<2) #define DCPSPUBLICATION_FLAG (1<<3) -#define CMPARTICIPANT_FLAG (1<<4) -#define CMPUBLISHER_FLAG (1<<5) -#define CMSUBSCRIBER_FLAG (1<<6) -#define CMDATAREADER_FLAG (1<<7) -#define CMDATAWRITER_FLAG (1<<8) -static struct topictab{ - const char *name; - const int flag; +static struct topictab { + const char *name; + const int flag; + void (*fun) (FILE *fp, dds_entity_t pp); } topictab[] = { - {"dcpstopic", DCPSTOPIC_FLAG}, - {"dcpsparticipant", DCPSPARTICIPANT_FLAG}, - {"dcpssubscription", DCPSSUBSCRIPTION_FLAG}, - {"dcpspublication", DCPSPUBLICATION_FLAG}, - {"cmparticipant", CMPARTICIPANT_FLAG}, - {"cmpublisher", CMPUBLISHER_FLAG}, - {"cmsubscriber", CMSUBSCRIBER_FLAG}, - {"cmdatareader", CMDATAREADER_FLAG}, - {"cmdatawriter", CMDATAWRITER_FLAG}, - + //{ "dcpstopic", DCPSTOPIC_FLAG, print_dcps_topic }, + { "dcpsparticipant", DCPSPARTICIPANT_FLAG, print_dcps_participant }, + { "dcpssubscription", DCPSSUBSCRIPTION_FLAG, print_dcps_subscription }, + { "dcpspublication", DCPSPUBLICATION_FLAG, print_dcps_publication } }; #define TOPICTAB_SIZE (sizeof(topictab)/sizeof(struct topictab)) -const unsigned int MAX_SAMPLES = 10; -unsigned int states = DDS_ANY_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE; -int reader_wait = 0; -dds_entity_t participant; -dds_entity_t subscriber; -dds_domainid_t did = DDS_DOMAIN_DEFAULT; -dds_sample_info_t info[10]; -dds_qos_t* tqos; -dds_qos_t* sqos; - -void _zero(void ** samples, size_t size) { - size_t i; - for(i = 0; i < size;i++) { - samples[i] = NULL; - } -} - -int duration_is_infinite(const DDS_Duration_t *d){ - return d->sec == DURATION_INFINITE_SEC && d->nanosec == DURATION_INFINITE_NSEC; -} - -void qp_durability (const DDS_DurabilityQosPolicy *q, FILE *fp) +void usage (void) { - char buf[40]; - char *k; - switch (q->kind) + fprintf (stderr, "Usage: ddsls [OPTIONS] TOPIC... for specified topics\n\n"); + fprintf (stderr, " or: ddsls [OPTIONS] -a for all topics\n"); + fprintf (stderr, "\nOPTIONS:\n"); + fprintf (stderr, "-f -- write to file\n"); + fprintf (stderr, "\nTOPICS\n"); + for (size_t i = 0; i < TOPICTAB_SIZE; i++) + fprintf (stderr, "%s\n", topictab[i].name); + exit (1); +} + +int main (int argc, char **argv) +{ + FILE *fp = stdout; + int flags = 0; + dds_entity_t pp; + int opt; + while ((opt = os_getopt (argc, argv, "f:a")) != EOF) + { + switch (opt) { - case DDS_VOLATILE_DURABILITY_QOS: k = "volatile"; break; - case DDS_TRANSIENT_LOCAL_DURABILITY_QOS: k = "transient-local"; break; - case DDS_TRANSIENT_DURABILITY_QOS: k = "transient"; break; - case DDS_PERSISTENT_DURABILITY_QOS: k = "persistent"; break; - default: (void) snprintf (buf, sizeof (buf), "invalid (%d)", (int) q->kind); k = buf; break; - } - fprintf (fp, " durability: kind = %s\n", k); -} - -void qp_deadline (const DDS_DeadlineQosPolicy *q, FILE *fp) -{ - fprintf (fp," deadline: period = "); - if (duration_is_infinite(&q->period)) - fprintf (fp, "infinite\n"); - else - fprintf (fp,"%d.%09u\n", q->period.sec, q->period.nanosec); -} - -void qp_latency_budget (const DDS_LatencyBudgetQosPolicy *q, FILE *fp) -{ - fprintf (fp," latency_budget: duration = "); - if (duration_is_infinite (&q->duration)) - fprintf (fp,"infinite\n"); - else - fprintf (fp,"%d.%09u\n", q->duration.sec, q->duration.nanosec); -} - -void qp_liveliness (const DDS_LivelinessQosPolicy *q, FILE *fp) -{ - char buf[40]; - char *k; - switch (q->kind) - { - case DDS_AUTOMATIC_LIVELINESS_QOS: k = "automatic"; break; - case DDS_MANUAL_BY_PARTICIPANT_LIVELINESS_QOS: k = "manual-by-participant"; break; - case DDS_MANUAL_BY_TOPIC_LIVELINESS_QOS: k = "manual-by-topic"; break; - default: (void) snprintf (buf, sizeof (buf), "invalid (%d)", (int) q->kind); k = buf; break; - } - fprintf (fp," liveliness: kind = %s, lease_duration = ", k); - if (duration_is_infinite(&q->lease_duration)) - fprintf (fp,"infinite\n"); - else - fprintf (fp,"%d.%09u\n", q->lease_duration.sec, q->lease_duration.nanosec); -} - -void qp_reliability (const DDS_ReliabilityQosPolicy *q, FILE *fp) -{ - char buf[40]; - char *k; - switch (q->kind) - { - case DDS_BEST_EFFORT_RELIABILITY_QOS: k = "best-effort"; break; - case DDS_RELIABLE_RELIABILITY_QOS: k = "reliable"; break; - default: (void) snprintf (buf, sizeof (buf), "invalid (%d)", (int) q->kind); k = buf; break; - } - fprintf (fp," reliability: kind = %s, max_blocking_time = ", k); - if (duration_is_infinite(&q->max_blocking_time)) - fprintf (fp,"infinite"); - else - fprintf (fp,"%d.%09u", q->max_blocking_time.sec, q->max_blocking_time.nanosec); - fprintf (fp,", synchronous = %s\n", q->synchronous ? "true" : "false"); -} - -void qp_transport_priority (const DDS_TransportPriorityQosPolicy *q, FILE *fp) -{ - fprintf (fp," transport_priority: priority = %d\n", q->value); -} - -void qp_lifespan (const DDS_LifespanQosPolicy *q, FILE *fp) -{ - fprintf (fp," lifespan: duration = "); - if (duration_is_infinite(&q->duration)) - fprintf (fp, "infinite\n"); - else - fprintf (fp, "%d.%09u\n", q->duration.sec, q->duration.nanosec); -} - -void qp_destination_order (const DDS_DestinationOrderQosPolicy *q, FILE *fp) -{ - char buf[40]; - char *k; - switch (q->kind) - { - case DDS_BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS: k = "by-reception-timestamp"; break; - case DDS_BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS: k = "by-source-timestamp"; break; - default: (void) snprintf (buf, sizeof (buf), "invalid (%d)", (int) q->kind); k = buf; break; - } - fprintf (fp," destination_order: kind = %s\n", k); -} - -void qp_history_kind_1 (DDS_HistoryQosPolicyKind kind, int indent, FILE *fp) -{ - char buf[40]; - char *k; - switch (kind) - { - case DDS_KEEP_LAST_HISTORY_QOS: k = "keep-last"; break; - case DDS_KEEP_ALL_HISTORY_QOS: k = "keep-all"; break; - default: (void) snprintf (buf, sizeof (buf), "invalid (%d)", (int) kind); k = buf; break; - } - fprintf (fp,"%*.*shistory: kind = %s", indent, indent, "", k); -} - -void qp_history (const DDS_HistoryQosPolicy *q, FILE *fp) -{ - qp_history_kind_1 (q->kind, 2,fp); - if (q->kind == DDS_KEEP_LAST_HISTORY_QOS) - fprintf (fp,", depth = %d\n", q->depth); - else - fprintf (fp,", (depth = %d)\n", q->depth); -} - -void qp_resource_limits_1(int max_samples, int max_instances, int max_samples_per_instance, int indent, FILE *fp) -{ - fprintf (fp,"%*.*sresource_limits: max_samples = ", indent, indent, ""); - if (max_samples == DDS_LENGTH_UNLIMITED) - fprintf (fp,"unlimited"); - else - fprintf (fp, "%d", max_samples); - fprintf (fp, ", max_instances = "); - if (max_instances == DDS_LENGTH_UNLIMITED) - fprintf (fp, "unlimited"); - else - fprintf (fp, "%d", max_instances); - fprintf (fp,", max_samples_per_instance = "); - if (max_samples_per_instance == DDS_LENGTH_UNLIMITED) - fprintf (fp,"unlimited\n"); - else - fprintf (fp,"%d\n", max_samples_per_instance); -} - -void qp_resource_limits (const DDS_ResourceLimitsQosPolicy *q, FILE *fp) -{ - qp_resource_limits_1 (q->max_samples, q->max_instances, q->max_samples_per_instance, 2,fp); -} - -void qp_ownership (const DDS_OwnershipQosPolicy *q, FILE *fp) -{ - char buf[40]; - char *k; - switch (q->kind) - { - case DDS_SHARED_OWNERSHIP_QOS: k = "shared"; break; - case DDS_EXCLUSIVE_OWNERSHIP_QOS: k = "exclusive"; break; - default: (void) snprintf (buf, sizeof (buf), "invalid (%d)", (int) q->kind); k = buf; break; - } - fprintf (fp," ownership: kind = %s\n", k); -} - -unsigned printable_seq_length(const unsigned char *as, unsigned n) -{ - unsigned i; - for (i = 0; i < n; i++) { - if (as[i] < 32 || as[i] >= 127) - break; - } - return i; -} - -void print_octetseq (const DDS_octSeq *v, FILE *fp) -{ - - unsigned i, n; - const char *sep = ""; - fprintf (fp, "%u<", v->_length); - i = 0; - while (i < v->_length) - { - if ((n = printable_seq_length (v->_buffer + i, v->_length - i)) < 4) + case 'f': { + char *fname = os_get_optarg (); + fp = fopen (fname, "w"); + if (fp == NULL) { - while (n--) - fprintf (fp,"%s%u", sep, v->_buffer[i++]); + fprintf (stderr, "%s: can't open for writing\n", fname); + exit (1); } - else - { - fprintf (fp, "\"%*.*s\"", n, n, v->_buffer + i); - i += n; - } - sep = ","; + break; + } + case 'a': + for (size_t i = 0; i < TOPICTAB_SIZE; i++) + flags |= topictab[i].flag; + break; + default: + usage (); + break; } - fprintf (fp,">"); -} + } -void qp_topic_data (const DDS_TopicDataQosPolicy *q, FILE *fp) -{ - fprintf (fp, " topic_data: value = "); - print_octetseq (&q->value,fp); - fprintf (fp, "\n"); -} + if (argc == 1) { + usage(); + } -void qp_user_data (const DDS_UserDataQosPolicy *q, FILE *fp) -{ - fprintf (fp, " user_data: value = "); - print_octetseq (&q->value,fp); - fprintf (fp, "\n"); -} - -void qp_time_based_filter (const DDS_TimeBasedFilterQosPolicy *q, FILE *fp) -{ - fprintf (fp," time_based_filter: minimum_separation = "); - if (duration_is_infinite (&q->minimum_separation)) - fprintf (fp,"infinite\n"); - else - fprintf (fp,"%d.%09u\n", q->minimum_separation.sec, q->minimum_separation.nanosec); -} - -void qp_presentation (const DDS_PresentationQosPolicy *q, FILE *fp) -{ - char buf[40]; - char *k; - switch (q->access_scope) + for (int i = os_get_optind (); i < argc; i++) + { + size_t k; + for (k = 0; k < TOPICTAB_SIZE; k++) { - case DDS_INSTANCE_PRESENTATION_QOS: k = "instance"; break; - case DDS_TOPIC_PRESENTATION_QOS: k = "topic"; break; - case DDS_GROUP_PRESENTATION_QOS: k = "group"; break; - default: (void) snprintf (buf, sizeof (buf), "invalid (%d)", (int) q->access_scope); k = buf; break; + if (os_strcasecmp (argv[i], topictab[k].name) == 0) + { + flags |= topictab[k].flag; + break; + } } - fprintf (fp, " presentation: scope = %s, coherent_access = %s, ordered_access = %s\n", k, - q->coherent_access ? "true" : "false", - q->ordered_access ? "true" : "false"); -} - -void qp_partition (const DDS_PartitionQosPolicy *q, FILE *fp) -{ - const DDS_StringSeq *s = &q->name; - fprintf (fp, " partition: name = "); - if (s->_length == 0) - fprintf (fp, "(default)"); - else if (s->_length == 1) - fprintf (fp, "%s", s->_buffer[0]); - else + if (k == TOPICTAB_SIZE) { - unsigned i; - fprintf (fp,"{"); - for (i = 0; i < s->_length; i++) - fprintf (fp, "%s%s", (i > 0) ? "," : "", s->_buffer[i]); - fprintf (fp,"}"); + fprintf(stderr, "%s: topic unknown\n", argv[i]); + exit (1); } - fprintf (fp,"\n"); -} - -void qp_group_data (const DDS_GroupDataQosPolicy *q, FILE *fp) -{ - fprintf (fp," group_data: value = "); - print_octetseq (&q->value,fp); - fprintf (fp,"\n"); -} - -void qp_ownership_strength (const DDS_OwnershipStrengthQosPolicy *q, FILE *fp) -{ - fprintf (fp," ownership_strength: value = %d\n", q->value); -} - -void qp_product_data (const DDS_ProductDataQosPolicy *q, FILE *fp) -{ - fprintf (fp," product_data: value = %s\n", q->value); -} - -void qp_entity_factory (const DDS_EntityFactoryQosPolicy *q, FILE *fp) -{ - fprintf (fp," entity_factory: autoenable_created_entities = %s\n", - q->autoenable_created_entities ? "true" : "false"); -} - -void qp_share (const DDS_ShareQosPolicy *q, FILE *fp) -{ - fprintf (fp," share: enable = %s", q->enable ? "true" : "false"); - if (q->enable) - fprintf (fp,", name = %s", q->name); - fprintf (fp,"\n"); -} - -void qp_writer_data_lifecycle (const DDS_WriterDataLifecycleQosPolicy *q, FILE *fp) -{ - fprintf (fp," writer_data_lifecycle: autodispose_unregistered_instances = %s, autopurge_suspended_samples_delay = ", - q->autodispose_unregistered_instances ? "true" : "false"); - if (duration_is_infinite (&q->autopurge_suspended_samples_delay)) - fprintf (fp,"infinite"); - else - fprintf (fp,"%d.%09u", q->autopurge_suspended_samples_delay.sec, q->autopurge_suspended_samples_delay.nanosec); - fprintf (fp,", autounregister_instance_delay = "); - if (duration_is_infinite (&q->autounregister_instance_delay)) - fprintf (fp,"infinite\n"); - else - fprintf (fp,"%d.%09u\n", q->autounregister_instance_delay.sec, q->autounregister_instance_delay.nanosec); -} - -void qp_reader_data_lifecycle (const DDS_ReaderDataLifecycleQosPolicy *q, FILE *fp) -{ - fprintf (fp," reader_data_lifecycle: autopurge_nowriter_samples_delay = "); - if (duration_is_infinite (&q->autopurge_nowriter_samples_delay)) - fprintf (fp,"infinite"); - else - fprintf (fp,"%d.%09u", q->autopurge_nowriter_samples_delay.sec, q->autopurge_nowriter_samples_delay.nanosec); - fprintf (fp,", autopurge_disposed_samples_delay = "); - if (duration_is_infinite (&q->autopurge_disposed_samples_delay)) - fprintf (fp,"infinite"); - else - fprintf (fp,"%d.%09u", q->autopurge_disposed_samples_delay.sec, q->autopurge_disposed_samples_delay.nanosec); - fprintf (fp,", enable_invalid_samples = %s\n", q->enable_invalid_samples ? "true" : "false"); -} - -void qp_subscription_keys (const DDS_UserKeyQosPolicy *q, FILE *fp) -{ - fprintf (fp," subscription_keys: enable = %s expression = %s\n", q->enable ? "true" : "false", q->expression); -} - -void qp_reader_lifespan (const DDS_ReaderLifespanQosPolicy *q, FILE *fp) -{ - fprintf (fp," reader_lifespan: use_lifespan = %s, ", q->use_lifespan ? "true" : "false"); - if (!q->use_lifespan) - fprintf (fp,"("); - fprintf (fp,"duration = "); - if (duration_is_infinite (&q->duration)) - fprintf (fp,"infinite"); - else - fprintf (fp,"%d.%09u", q->duration.sec, q->duration.nanosec); - if (!q->use_lifespan) - fprintf (fp,")"); - fprintf (fp,"\n"); -} - -void print_dcps_topic(FILE *fp){ - DDS_TopicBuiltinTopicData * dcps_topic_samples[10]; - dds_entity_t dcps_topic_reader; - int i = 0; - dcps_topic_reader = dds_create_reader(participant, DDS_BUILTIN_TOPIC_DCPSTOPIC, NULL, NULL); - PRINTD("DCPSTopic Reader Create: %s\n", dds_err_str(dcps_topic_reader)); - reader_wait = dds_reader_wait_for_historical_data(dcps_topic_reader, DDS_SECS(5)); - PRINTD("reader wait status: %d, %s \n", reader_wait, dds_err_str(reader_wait)); - while(true){ - int status = 0; - zero(dcps_topic_samples, MAX_SAMPLES); - status = dds_take_mask(dcps_topic_reader, (void**)dcps_topic_samples, info, MAX_SAMPLES, MAX_SAMPLES, states); - PRINTD("DDS reading samples returns %d \n", status); - for(i = 0; i < status; i++) { - DDS_TopicBuiltinTopicData * data = dcps_topic_samples[i]; - fprintf(fp,"TOPIC:\n"); - fprintf(fp," key = %u:%u:%u \n", (unsigned) data->key[0], (unsigned) data->key[1], (unsigned) data->key[2]); - fprintf(fp," name = %s\n", data->name); - fprintf(fp," type_name = %s\n", data->type_name); - qp_durability (&data->durability,fp); - qp_deadline (&data->deadline,fp); - qp_latency_budget (&data->latency_budget,fp); - qp_liveliness (&data->liveliness,fp); - qp_reliability (&data->reliability,fp); - qp_transport_priority (&data->transport_priority,fp); - qp_lifespan (&data->lifespan,fp); - qp_destination_order (&data->destination_order,fp); - qp_history (&data->history,fp); - qp_resource_limits (&data->resource_limits,fp); - qp_ownership (&data->ownership,fp); - qp_topic_data (&data->topic_data,fp); - } - if(status > 0) { - status = dds_return_loan(dcps_topic_reader, (void**)dcps_topic_samples, status); - } - if(status <= 0){ - break; - } - } -} - -void print_dcps_participant(FILE *fp){ - - DDS_ParticipantBuiltinTopicData * dcps_participant_samples[10]; - dds_entity_t dcps_participant_reader; - int i = 0; - dcps_participant_reader = dds_create_reader(participant, DDS_BUILTIN_TOPIC_DCPSPARTICIPANT, NULL, NULL); - PRINTD("DCPSSubscription Reader Create: %s\n", dds_err_str(dcps_participant_reader)); - reader_wait = dds_reader_wait_for_historical_data(dcps_participant_reader, DDS_SECS(5)); - PRINTD("reader wait status: %d, %s \n", reader_wait, dds_err_str(reader_wait)); - while(true){ - int status = 0; - zero(dcps_participant_samples, MAX_SAMPLES); - status = dds_take_mask(dcps_participant_reader, (void**)dcps_participant_samples, info, MAX_SAMPLES, MAX_SAMPLES, states); - PRINTD("DDS reading samples returns %d \n", status); - for(i = 0; i < status; i++) { - DDS_ParticipantBuiltinTopicData *data = dcps_participant_samples[i]; - fprintf(fp,"PARTICIPANT:\n"); - fprintf(fp," key = %u:%u:%u \n", (unsigned) data->key[0], (unsigned) data->key[1], (unsigned) data->key[2]); - qp_user_data(&data->user_data,fp); - } - if(status > 0) { - status = dds_return_loan(dcps_participant_reader, (void**)dcps_participant_samples, status); - } - if(status <= 0){ - break; - } - } -} - -void print_dcps_subscription(FILE *fp){ - DDS_SubscriptionBuiltinTopicData * dcps_subscription_samples[10]; - dds_entity_t dcps_subscription_reader; - int i = 0; - dcps_subscription_reader = dds_create_reader(participant, DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION, NULL, NULL); - PRINTD("DCPSParticipant Reader Create: %s\n", dds_err_str(dcps_subscription_reader)); - reader_wait = dds_reader_wait_for_historical_data(dcps_subscription_reader, DDS_SECS(5)); - PRINTD("reader wait status: %d, %s \n", reader_wait, dds_err_str(reader_wait)); - while(true){ - int status = 0; - zero(dcps_subscription_samples, MAX_SAMPLES); - status = dds_take_mask(dcps_subscription_reader, (void**)dcps_subscription_samples, info, MAX_SAMPLES, MAX_SAMPLES, states); - PRINTD("DDS reading samples returns %d \n", status); - for(i = 0; i < status; i++) { - DDS_SubscriptionBuiltinTopicData *data = dcps_subscription_samples[i]; - fprintf(fp,"SUBSCRIPTION:\n"); - fprintf(fp," key = %u:%u:%u\n", (uint32_t) data->key[0], (uint32_t) data->key[1], (uint32_t) data->key[2]); - fprintf(fp," participant_key = %u:%u:%u\n", (uint32_t) data->participant_key[0], (uint32_t) data->participant_key[1], (uint32_t) data->participant_key[2]); - fprintf(fp," topic_name = %s\n", data->topic_name); - fprintf(fp," type_name = %s\n", data->type_name); - qp_durability(&data->durability,fp); - qp_deadline(&data->deadline,fp); - qp_latency_budget(&data->latency_budget,fp); - qp_liveliness(&data->liveliness,fp); - qp_reliability(&data->reliability,fp); - qp_ownership(&data->ownership,fp); - qp_destination_order(&data->destination_order,fp); - qp_user_data(&data->user_data,fp); - qp_time_based_filter(&data->time_based_filter,fp); - qp_presentation(&data->presentation,fp); - qp_partition(&data->partition,fp); - qp_topic_data(&data->topic_data,fp); - qp_group_data(&data->group_data,fp); - } - if(status > 0) { - status = dds_return_loan(dcps_subscription_reader, (void**)dcps_subscription_samples, status); - } - if(status <= 0){ - break; - } - } -} - -void print_dcps_publication(FILE *fp){ - DDS_PublicationBuiltinTopicData * dcps_publication_samples[10]; - dds_entity_t dcps_publication_reader; - int i = 0; - dcps_publication_reader = dds_create_reader(participant, DDS_BUILTIN_TOPIC_DCPSPUBLICATION, NULL, NULL); - PRINTD("DCPSPublication Reader Create: %s\n", dds_err_str(dcps_publication_reader)); - reader_wait = dds_reader_wait_for_historical_data(dcps_publication_reader, DDS_SECS(5)); - PRINTD("reader wait status: %d, %s \n", reader_wait, dds_err_str(reader_wait)); - while(true){ - int status = 0; - zero(dcps_publication_samples, MAX_SAMPLES); - status = dds_take_mask(dcps_publication_reader, (void**)dcps_publication_samples, info, MAX_SAMPLES, MAX_SAMPLES, states); - PRINTD("DDS reading samples returns %d \n", status); - for(i = 0; i < status; i++) { - DDS_PublicationBuiltinTopicData *data = dcps_publication_samples[i]; - fprintf(fp,"PUBLICATION:\n"); - fprintf(fp," key = %u:%u:%u\n", (uint32_t) data->key[0], (uint32_t) data->key[1], (uint32_t) data->key[2]); - fprintf(fp," participant_key = %u:%u:%u\n", (uint32_t) data->participant_key[0], (uint32_t) data->participant_key[1], (uint32_t) data->participant_key[2]); - fprintf(fp," topic_name = %s\n", data->topic_name); - fprintf(fp," type_name = %s\n", data->type_name); - qp_durability(&data->durability,fp); - qp_deadline(&data->deadline,fp); - qp_latency_budget(&data->latency_budget,fp); - qp_liveliness(&data->liveliness,fp); - qp_reliability(&data->reliability,fp); - qp_lifespan (&data->lifespan,fp); - qp_destination_order (&data->destination_order,fp); - qp_user_data (&data->user_data,fp); - qp_ownership (&data->ownership,fp); - qp_ownership_strength (&data->ownership_strength,fp); - qp_presentation (&data->presentation,fp); - qp_partition (&data->partition,fp); - qp_topic_data (&data->topic_data,fp); - qp_group_data (&data->group_data,fp); - } - if(status > 0) { - status = dds_return_loan(dcps_publication_reader, (void**)dcps_publication_samples, status); - } - if(status <= 0){ - break; - } - } -} - -void print_cm_participant(FILE *fp){ - DDS_CMParticipantBuiltinTopicData * cm_participant_samples[10]; - dds_entity_t cm_participant_reader; - int i = 0; - cm_participant_reader = dds_create_reader(participant, DDS_BUILTIN_TOPIC_CMPARTICIPANT, NULL, NULL); - PRINTD("CMParticipant Reader Create: %s\n", dds_err_str(cm_participant_reader)); - reader_wait = dds_reader_wait_for_historical_data(cm_participant_reader, DDS_SECS(5)); - PRINTD("reader wait status: %d, %s \n", reader_wait, dds_err_str(reader_wait)); - while(true){ - int status = 0; - zero(cm_participant_samples, MAX_SAMPLES); - status = dds_take_mask(cm_participant_reader, (void**)cm_participant_samples, info, MAX_SAMPLES, MAX_SAMPLES, states); - PRINTD("DDS reading samples returns %d \n", status); - for(i = 0; i < status; i++) { - DDS_CMParticipantBuiltinTopicData *data = cm_participant_samples[i]; - fprintf(fp,"CMPARTICIPANT:\n"); - fprintf(fp," key = %u:%u:%u \n", (unsigned) data->key[0], (unsigned) data->key[1], (unsigned) data->key[2]); - qp_product_data(&data->product,fp); - } - if(status > 0) { - status = dds_return_loan(cm_participant_reader, (void**)cm_participant_samples, status); - } - if(status <= 0){ - break; - } - } -} - -void print_cm_publisher(FILE *fp){ - DDS_CMPublisherBuiltinTopicData * cm_publisher_samples[10]; - dds_entity_t cm_publisher_reader; - int i = 0; - cm_publisher_reader = dds_create_reader(participant, DDS_BUILTIN_TOPIC_CMPUBLISHER, NULL, NULL); - PRINTD("CMPublisher Reader Create: %s\n", dds_err_str(cm_publisher_reader)); - reader_wait = dds_reader_wait_for_historical_data(cm_publisher_reader, DDS_SECS(5)); - PRINTD("reader wait status: %d, %s \n", reader_wait, dds_err_str(reader_wait)); - while(true){ - int status = 0; - zero(cm_publisher_samples, MAX_SAMPLES); - status = dds_take_mask(cm_publisher_reader, (void**)cm_publisher_samples, info, MAX_SAMPLES, MAX_SAMPLES, states); - PRINTD("DDS reading samples returns %d \n", status); - for(i = 0; i < status; i++) { - DDS_CMPublisherBuiltinTopicData *data = cm_publisher_samples[i]; - fprintf(fp,"CMPUBLISHER:\n"); - fprintf(fp," key = %u:%u:%u \n", (unsigned) data->key[0], (unsigned) data->key[1], (unsigned) data->key[2]); - fprintf(fp," participant_key = %u:%u:%u\n", (unsigned) data->key[0], (unsigned) data->key[1], (unsigned) data->key[2]); - fprintf(fp," name = %s\n", data->name); - qp_entity_factory(&data->entity_factory,fp); - qp_partition(&data->partition,fp); - qp_product_data(&data->product,fp); - } - if(status > 0) { - status = dds_return_loan(cm_publisher_reader, (void**)cm_publisher_samples, status); - } - if(status <= 0){ - break; - } - } -} - -void print_cm_subscriber(FILE *fp){ - DDS_CMSubscriberBuiltinTopicData * cm_subscriber_samples[10]; - dds_entity_t cm_subscriber_reader; - int i = 0; - cm_subscriber_reader = dds_create_reader(participant, DDS_BUILTIN_TOPIC_CMSUBSCRIBER, NULL, NULL); - PRINTD("CMSubscriber Reader Create: %s\n", dds_err_str(cm_subscriber_reader)); - reader_wait = dds_reader_wait_for_historical_data(cm_subscriber_reader, DDS_SECS(5)); - PRINTD("reader wait status: %d, %s \n", reader_wait, dds_err_str(reader_wait)); - while(true){ - int status = 0; - zero(cm_subscriber_samples, MAX_SAMPLES); - status = dds_take_mask(cm_subscriber_reader, (void**)cm_subscriber_samples, info, MAX_SAMPLES, MAX_SAMPLES, states); - PRINTD("DDS reading samples returns %d \n", status); - for(i = 0; i < status; i++) { - DDS_CMSubscriberBuiltinTopicData *data = cm_subscriber_samples[i]; - fprintf(fp,"CMSUBSCRIBER:\n"); - fprintf(fp," key = %u:%u:%u \n", (unsigned) data->key[0], (unsigned) data->key[1], (unsigned) data->key[2]); - fprintf(fp," participant_key = %u:%u:%u\n", (unsigned) data->participant_key[0], (unsigned) data->participant_key[1], (unsigned) data->participant_key[2]); - fprintf(fp," name = %s\n", data->name); - qp_entity_factory(&data->entity_factory,fp); - qp_partition(&data->partition,fp); - qp_share(&data->share,fp); - qp_product_data(&data->product,fp); - } - if(status > 0) { - status = dds_return_loan(cm_subscriber_reader, (void**)cm_subscriber_samples, status); - } - if(status <= 0){ - break; - } - } -} - -void print_cm_datawriter(FILE *fp){ - DDS_CMDataWriterBuiltinTopicData * cm_datawriter_samples[10]; - dds_entity_t cm_datawriter_reader; - int i = 0; - cm_datawriter_reader = dds_create_reader(participant, DDS_BUILTIN_TOPIC_CMDATAWRITER, NULL, NULL); - PRINTD("CMDataWriter Reader Create: %s\n", dds_err_str(cm_datawriter_reader)); - reader_wait = dds_reader_wait_for_historical_data(cm_datawriter_reader, DDS_SECS(5)); - PRINTD("reader wait status: %d, %s \n", reader_wait, dds_err_str(reader_wait)); - while(true){ - int status = 0; - zero(cm_datawriter_samples, MAX_SAMPLES); - status = dds_take_mask(cm_datawriter_reader, (void**)cm_datawriter_samples, info, MAX_SAMPLES, MAX_SAMPLES, states); - PRINTD("DDS reading samples returns %d \n", status); - for(i = 0; i < status; i++) { - DDS_CMDataWriterBuiltinTopicData *data = cm_datawriter_samples[i]; - fprintf(fp,"CMDATAWRITER:\n"); - fprintf(fp," key = %u:%u:%u \n", (unsigned) data->key[0], (unsigned) data->key[1], (unsigned) data->key[2]); - fprintf(fp," publisher_key = %u:%u:%u\n", (unsigned) data->publisher_key[0], (unsigned) data->publisher_key[1], (unsigned) data->publisher_key[2]); - fprintf(fp," name = %s\n", data->name); - qp_history (&data->history,fp); - qp_resource_limits (&data->resource_limits,fp); - qp_writer_data_lifecycle (&data->writer_data_lifecycle,fp); - qp_product_data (&data->product,fp); - } - if(status > 0) { - status = dds_return_loan(cm_datawriter_reader, (void**)cm_datawriter_samples, status); - } - if(status <= 0){ - break; - } - } -} - -void print_cm_datareader(FILE *fp){ - DDS_CMDataReaderBuiltinTopicData * cm_datareader_samples[10]; - dds_entity_t cm_datareader_reader; - int i = 0; - cm_datareader_reader = dds_create_reader(participant, DDS_BUILTIN_TOPIC_CMDATAREADER, NULL, NULL); - PRINTD("CMDataReader Reader Create: %s\n", dds_err_str(cm_datareader_reader)); - reader_wait = dds_reader_wait_for_historical_data(cm_datareader_reader, DDS_SECS(5)); - PRINTD("reader wait status: %d, %s \n", reader_wait, dds_err_str(reader_wait)); - while(true){ - int status = 0; - zero(cm_datareader_samples, MAX_SAMPLES); - status = dds_take_mask(cm_datareader_reader, (void**)cm_datareader_samples, info, MAX_SAMPLES, MAX_SAMPLES, states); - PRINTD("DDS reading samples returns %d \n", status); - for(i = 0; i < status; i++) { - DDS_CMDataReaderBuiltinTopicData *data = cm_datareader_samples[i]; - fprintf(fp,"CMDATAREADER:\n"); - fprintf(fp," key = %u:%u:%u \n", (unsigned) data->key[0], (unsigned) data->key[1], (unsigned) data->key[2]); - fprintf(fp," subscriber_key = %u:%u:%u\n", (unsigned) data->subscriber_key[0], (unsigned) data->subscriber_key[1], (unsigned) data->subscriber_key[2]); - fprintf(fp," name = %s\n", data->name); - qp_history (&data->history,fp); - qp_resource_limits (&data->resource_limits,fp); - qp_reader_data_lifecycle (&data->reader_data_lifecycle,fp); - qp_subscription_keys (&data->subscription_keys,fp); - qp_reader_lifespan (&data->reader_lifespan,fp); - qp_share (&data->share,fp); - qp_product_data (&data->product,fp); - } - if(status > 0) { - status = dds_return_loan(cm_datareader_reader, (void**)cm_datareader_samples, status); - } - if(status <= 0){ - break; - } - } -} - -void usage(){ - /*describe the default options*/ - size_t tpindex; - printf("\n OPTIONS:\n"); - printf("-f -- write to file\n"); - printf("-a -- all topics\n"); - printf("\nTOPICS\n"); - for(tpindex = 0; tpindex < TOPICTAB_SIZE; tpindex++){ - printf("%s\n", topictab[tpindex].name); - } -} - -int main(int argc, char **argv){ - FILE *fp = NULL; - int flags = 0; - int j; - size_t index; - char *fname = NULL; - if(argc == 1){ - usage(); - } - int choice=0; - while((choice = os_getopt(argc,argv,"f:a")) != -1) - { - switch(choice) - { - case 'f': - fname = os_get_optarg(); - if(fname != NULL){ - - PRINTD("opening file %s \n", fname); - fp = fopen(fname, "w"); - if(fp == NULL) - { - printf("file does not exist\n"); - exit(1); - } - } - break; - case 'a': - for(index=0; index