diff --git a/src/core/ddsc/CMakeLists.txt b/src/core/ddsc/CMakeLists.txt index b29de10..f9c5ff4 100644 --- a/src/core/ddsc/CMakeLists.txt +++ b/src/core/ddsc/CMakeLists.txt @@ -13,7 +13,6 @@ PREPEND(srcs_ddsc "${CMAKE_CURRENT_LIST_DIR}/src" dds_alloc.c dds_builtin.c dds_coherent.c - dds_iid.c dds_participant.c dds_reader.c dds_writer.c @@ -24,7 +23,6 @@ PREPEND(srcs_ddsc "${CMAKE_CURRENT_LIST_DIR}/src" dds_domain.c dds_instance.c dds_qos.c - dds_tkmap.c dds_entity.c dds_key.c dds_querycond.c @@ -57,7 +55,6 @@ PREPEND(hdrs_private_ddsc "${CMAKE_CURRENT_LIST_DIR}/src" dds__builtin.h dds__domain.h dds__entity.h - dds__iid.h dds__init.h dds__key.h dds__listener.h @@ -71,7 +68,6 @@ PREPEND(hdrs_private_ddsc "${CMAKE_CURRENT_LIST_DIR}/src" dds__rhc.h dds__stream.h dds__subscriber.h - dds__tkmap.h dds__topic.h dds__types.h dds__write.h @@ -93,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 "$") @@ -131,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 1044c4a..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 @@ -177,6 +170,29 @@ typedef struct dds_sample_info } dds_sample_info_t; +typedef struct dds_builtintopic_guid +{ + uint8_t v[16]; +} +dds_builtintopic_guid_t; + +typedef struct dds_builtintopic_participant +{ + dds_builtintopic_guid_t key; + dds_qos_t *qos; +} +dds_builtintopic_participant_t; + +typedef struct dds_builtintopic_endpoint +{ + dds_builtintopic_guid_t key; + dds_builtintopic_guid_t participant_key; + char *topic_name; + char *type_name; + dds_qos_t *qos; +} +dds_builtintopic_endpoint_t; + /* All entities are represented by a process-private handle, with one call to enable an entity when it was created disabled. @@ -947,7 +963,7 @@ dds_lookup_participant( _In_ size_t size); /** - * @brief Creates a new topic. + * @brief Creates a new topic with default type handling. * * The type name for the topic is taken from the generated descriptor. Topic * matching is done on a combination of topic name and type name. @@ -975,6 +991,39 @@ dds_create_topic( _In_opt_ const dds_qos_t *qos, _In_opt_ const dds_listener_t *listener); +/** + * @brief Creates a new topic with arbitrary type handling. + * + * The type name for the topic is taken from the provided "sertopic" object. Topic + * matching is done on a combination of topic name and type name. + * + * @param[in] participant Participant on which to create the topic. + * @param[in] sertopic Internal description of the topic type. + * @param[in] name Name of the topic. + * @param[in] qos QoS to set on the new topic (can be NULL). + * @param[in] listener Any listener functions associated with the new topic (can be NULL). + * @param[in] sedp_plist Topic description to be published as part of discovery (if NULL, not published). + * + * @returns A valid topic handle or an error code. + * + * @retval >=0 + * A valid topic handle. + * @retval DDS_RETCODE_BAD_PARAMETER + * Either participant, descriptor, name or qos is invalid. + */ +/* TODO: Check list of retcodes is complete. */ +struct ddsi_sertopic; +struct nn_plist; +_Pre_satisfies_((participant & DDS_ENTITY_KIND_MASK) == DDS_KIND_PARTICIPANT) +DDS_EXPORT dds_entity_t +dds_create_topic_arbitrary ( + _In_ dds_entity_t participant, + _In_ struct ddsi_sertopic *sertopic, + _In_z_ const char *name, + _In_opt_ const dds_qos_t *qos, + _In_opt_ const dds_listener_t *listener, + _In_opt_ const struct nn_plist *sedp_plist); + /** * @brief Finds a named topic. * @@ -3037,7 +3086,7 @@ dds_read_next_wl( _Pre_satisfies_(((reader_or_condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\ ((reader_or_condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \ ((reader_or_condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY )) -DDS_EXPORT _Must_inspect_result_ dds_return_t +DDS_EXPORT dds_return_t dds_return_loan( _In_ dds_entity_t reader_or_condition, _Inout_updates_(bufsz) void **buf, 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__rhc.h b/src/core/ddsc/src/dds__rhc.h index 13ff911..3007692 100644 --- a/src/core/ddsc/src/dds__rhc.h +++ b/src/core/ddsc/src/dds__rhc.h @@ -24,7 +24,7 @@ extern "C" { struct rhc; struct nn_xqos; struct ddsi_serdata; -struct tkmap_instance; +struct ddsi_tkmap_instance; struct proxy_writer_info; struct rhc * dds_rhc_new (dds_reader * reader, const struct ddsi_sertopic * topic); @@ -36,7 +36,7 @@ uint32_t dds_rhc_lock_samples (struct rhc * rhc); DDS_EXPORT bool dds_rhc_store ( struct rhc * __restrict rhc, const struct proxy_writer_info * __restrict pwr_info, - struct ddsi_serdata * __restrict sample, struct tkmap_instance * __restrict tk + struct ddsi_serdata * __restrict sample, struct ddsi_tkmap_instance * __restrict tk ); void dds_rhc_unregister_wr (struct rhc * __restrict rhc, const struct proxy_writer_info * __restrict pwr_info); void dds_rhc_relinquish_ownership (struct rhc * __restrict rhc, const uint64_t wr_iid); diff --git a/src/core/ddsc/src/dds__tkmap.h b/src/core/ddsc/src/dds__tkmap.h deleted file mode 100644 index c25be3e..0000000 --- a/src/core/ddsc/src/dds__tkmap.h +++ /dev/null @@ -1,52 +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 _DDS_TKMAP_H_ -#define _DDS_TKMAP_H_ - -#include "dds__types.h" -#include "os/os_atomics.h" - -#if defined (__cplusplus) -extern "C" { -#endif - -struct tkmap; -struct ddsi_serdata; -struct dds_topic; - -struct tkmap_instance -{ - struct ddsi_serdata * m_sample; - struct tkmap * m_map; - uint64_t m_iid; - os_atomic_uint32_t m_refc; -}; - - -struct tkmap * dds_tkmap_new (void); -void dds_tkmap_free (_Inout_ _Post_invalid_ struct tkmap *tkmap); -void dds_tkmap_instance_ref (_In_ struct tkmap_instance *tk); -uint64_t dds_tkmap_lookup (_In_ struct tkmap *tkmap, _In_ const struct ddsi_serdata *serdata); -_Check_return_ bool dds_tkmap_get_key (_In_ struct tkmap * map, const struct ddsi_sertopic *topic, _In_ uint64_t iid, _Out_ void * sample); -_Check_return_ struct tkmap_instance * dds_tkmap_find( - _In_ struct ddsi_serdata * sd, - _In_ const bool rd, - _In_ const bool create); -_Check_return_ struct tkmap_instance * dds_tkmap_find_by_id (_In_ struct tkmap * map, _In_ uint64_t iid); - -DDS_EXPORT _Check_return_ struct tkmap_instance * dds_tkmap_lookup_instance_ref (_In_ struct ddsi_serdata * sd); -DDS_EXPORT void dds_tkmap_instance_unref (_In_ struct tkmap_instance * tk); - -#if defined (__cplusplus) -} -#endif -#endif diff --git a/src/core/ddsc/src/dds__types.h b/src/core/ddsc/src/dds__types.h index 4821c76..ab6edb0 100644 --- a/src/core/ddsc/src/dds__types.h +++ b/src/core/ddsc/src/dds__types.h @@ -169,7 +169,7 @@ typedef struct dds_reader struct reader * m_rd; bool m_data_on_readers; bool m_loan_out; - char * m_loan; + void * m_loan; uint32_t m_loan_size; /* Status metrics */ @@ -209,7 +209,6 @@ typedef struct dds_topic { struct dds_entity m_entity; struct ddsi_sertopic * m_stopic; - const dds_topic_descriptor_t * m_descriptor; dds_topic_intern_filter_fn filter_fn; void * filter_ctx; @@ -259,13 +258,6 @@ typedef struct dds_waitset } dds_waitset; -typedef struct dds_iid -{ - uint64_t counter; - uint32_t key[4]; -} -dds_iid; - /* Globals */ typedef struct dds_globals 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_domain.c b/src/core/ddsc/src/dds_domain.c index 4b3e23e..4c10db5 100644 --- a/src/core/ddsc/src/dds_domain.c +++ b/src/core/ddsc/src/dds_domain.c @@ -10,7 +10,7 @@ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause */ #include "dds__domain.h" -#include "dds__tkmap.h" +#include "ddsi/ddsi_tkmap.h" static int dds_domain_compare (const int32_t * a, const int32_t * b) { diff --git a/src/core/ddsc/src/dds_init.c b/src/core/ddsc/src/dds_init.c index 5759f75..cc224c4 100644 --- a/src/core/ddsc/src/dds_init.c +++ b/src/core/ddsc/src/dds_init.c @@ -15,11 +15,11 @@ #include "os/os.h" #include "dds__init.h" #include "dds__rhc.h" -#include "dds__tkmap.h" -#include "dds__iid.h" #include "dds__domain.h" #include "dds__err.h" #include "dds__builtin.h" +#include "ddsi/ddsi_iid.h" +#include "ddsi/ddsi_tkmap.h" #include "ddsi/ddsi_serdata.h" #include "ddsi/q_servicelease.h" #include "ddsi/q_entity.h" @@ -239,7 +239,6 @@ extern void dds_fini (void) static int dds__init_plugin (void) { - dds_iid_init (); if (dds_global.m_dur_init) (dds_global.m_dur_init) (); return 0; } @@ -247,17 +246,14 @@ static int dds__init_plugin (void) static void dds__fini_plugin (void) { if (dds_global.m_dur_fini) (dds_global.m_dur_fini) (); - dds_iid_fini (); } 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; @@ -265,12 +261,6 @@ void ddsi_plugin_init (void) ddsi_plugin.rhc_plugin.rhc_unregister_wr_fn = dds_rhc_unregister_wr; ddsi_plugin.rhc_plugin.rhc_relinquish_ownership_fn = dds_rhc_relinquish_ownership; ddsi_plugin.rhc_plugin.rhc_set_qos_fn = dds_rhc_set_qos; - ddsi_plugin.rhc_plugin.rhc_lookup_fn = dds_tkmap_lookup_instance_ref; - ddsi_plugin.rhc_plugin.rhc_unref_fn = dds_tkmap_instance_unref; - - /* Register iid generator */ - - ddsi_plugin.iidgen_fn = dds_iid_gen; } diff --git a/src/core/ddsc/src/dds_instance.c b/src/core/ddsc/src/dds_instance.c index f1f6ec4..1fbaa0c 100644 --- a/src/core/ddsc/src/dds_instance.c +++ b/src/core/ddsc/src/dds_instance.c @@ -16,8 +16,8 @@ #include "dds__write.h" #include "dds__writer.h" #include "dds__rhc.h" -#include "dds__tkmap.h" #include "dds__err.h" +#include "ddsi/ddsi_tkmap.h" #include "ddsi/ddsi_serdata.h" #include "ddsi/q_entity.h" #include "ddsi/q_thread.h" @@ -50,14 +50,14 @@ dds_dispose_ih( return dds_dispose_ih_ts(writer, handle, dds_time()); } -static struct tkmap_instance* +static struct ddsi_tkmap_instance* dds_instance_find( _In_ const dds_topic *topic, _In_ const void *data, _In_ const bool create) { struct ddsi_serdata *sd = ddsi_serdata_from_sample (topic->m_stopic, SDK_KEY, data); - struct tkmap_instance * inst = dds_tkmap_find (sd, false, create); + struct ddsi_tkmap_instance * inst = ddsi_tkmap_find (sd, false, create); ddsi_serdata_unref (sd); return inst; } @@ -68,10 +68,10 @@ dds_instance_remove( _In_opt_ const void *data, _In_ dds_instance_handle_t handle) { - struct tkmap_instance * inst; + struct ddsi_tkmap_instance * inst; if (handle != DDS_HANDLE_NIL) { - inst = dds_tkmap_find_by_id (gv.m_tkmap, handle); + inst = ddsi_tkmap_find_by_id (gv.m_tkmap, handle); } else { assert (data); inst = dds_instance_find (topic, data, false); @@ -83,7 +83,7 @@ dds_instance_remove( if (asleep) { thread_state_awake(thr); } - dds_tkmap_instance_unref (inst); + ddsi_tkmap_instance_unref (inst); if (asleep) { thread_state_asleep(thr); } @@ -133,7 +133,7 @@ dds_register_instance( _Out_ dds_instance_handle_t *handle, _In_ const void *data) { - struct tkmap_instance * inst; + struct ddsi_tkmap_instance * inst; dds_entity *wr; dds_return_t ret; dds__retcode_t rc; @@ -241,7 +241,7 @@ dds_unregister_instance_ih_ts( bool autodispose = true; dds_write_action action = DDS_WR_ACTION_UNREGISTER; dds_entity *wr; - struct tkmap *map; + struct ddsi_tkmap *map; const dds_topic *topic; void *sample; @@ -262,15 +262,14 @@ dds_unregister_instance_ih_ts( map = gv.m_tkmap; topic = dds_instance_info((dds_entity*)wr); - sample = dds_alloc (topic->m_descriptor->m_size); - if (dds_tkmap_get_key (map, topic->m_stopic, handle, sample)) { + sample = ddsi_sertopic_alloc_sample (topic->m_stopic); + if (ddsi_tkmap_get_key (map, topic->m_stopic, handle, sample)) { ret = dds_write_impl ((dds_writer*)wr, sample, timestamp, action); } else{ DDS_ERROR("No instance related with the provided handle is found\n"); ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET); } - dds_sample_free (sample, topic->m_descriptor, DDS_FREE_ALL); - + ddsi_sertopic_free_sample (topic->m_stopic, sample, DDS_FREE_ALL); dds_entity_unlock(wr); err: return ret; @@ -354,16 +353,16 @@ dds_dispose_ih_ts( rc = dds_writer_lock(writer, &wr); if (rc == DDS_RETCODE_OK) { - struct tkmap *map = gv.m_tkmap; + struct ddsi_tkmap *map = gv.m_tkmap; const dds_topic *topic = dds_instance_info((dds_entity*)wr); - void *sample = dds_alloc (topic->m_descriptor->m_size); - if (dds_tkmap_get_key (map, topic->m_stopic, handle, sample)) { + void *sample = ddsi_sertopic_alloc_sample (topic->m_stopic); + if (ddsi_tkmap_get_key (map, topic->m_stopic, handle, sample)) { ret = dds_dispose_impl(wr, sample, handle, timestamp); } else { DDS_ERROR("No instance related with the provided handle is found\n"); ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET); } - dds_free(sample); + ddsi_sertopic_free_sample (topic->m_stopic, sample, DDS_FREE_ALL); dds_writer_unlock(wr); } else { DDS_ERROR("Error occurred on locking writer\n"); @@ -381,7 +380,7 @@ dds_instance_lookup( { dds_instance_handle_t ih = DDS_HANDLE_NIL; const dds_topic * topic; - struct tkmap * map = gv.m_tkmap; + struct ddsi_tkmap * map = gv.m_tkmap; struct ddsi_serdata *sd; if(data == NULL){ @@ -392,7 +391,7 @@ dds_instance_lookup( topic = dds_instance_info_by_hdl (entity); if (topic) { sd = ddsi_serdata_from_sample (topic->m_stopic, SDK_KEY, data); - ih = dds_tkmap_lookup (map, sd); + ih = ddsi_tkmap_lookup (map, sd); ddsi_serdata_unref (sd); } else { DDS_ERROR("Acquired topic is NULL\n"); @@ -410,7 +409,7 @@ dds_instance_get_key( { dds_return_t ret; const dds_topic * topic; - struct tkmap * map = gv.m_tkmap; + struct ddsi_tkmap * map = gv.m_tkmap; if(data == NULL){ DDS_ERROR("Argument data is NULL\n"); @@ -424,9 +423,8 @@ dds_instance_get_key( ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER); goto err; } - memset (data, 0, topic->m_descriptor->m_size); - - if (dds_tkmap_get_key (map, topic->m_stopic, inst, data)) { + ddsi_sertopic_zero_sample (topic->m_stopic, data); + if (ddsi_tkmap_get_key (map, topic->m_stopic, inst, data)) { ret = DDS_RETCODE_OK; } else{ DDS_ERROR("No instance related with the provided entity is found\n"); 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_read.c b/src/core/ddsc/src/dds_read.c index 6133dd7..ef7f16f 100644 --- a/src/core/ddsc/src/dds_read.c +++ b/src/core/ddsc/src/dds_read.c @@ -13,12 +13,13 @@ #include #include "dds__entity.h" #include "dds__reader.h" -#include "dds__tkmap.h" +#include "ddsi/ddsi_tkmap.h" #include "dds__rhc.h" #include "dds__err.h" #include "ddsi/q_thread.h" #include "ddsi/q_ephash.h" #include "ddsi/q_entity.h" +#include "ddsi/ddsi_sertopic.h" static _Check_return_ dds__retcode_t @@ -93,7 +94,6 @@ dds_read_impl( _In_ bool lock, _In_ bool only_reader) { - uint32_t i; dds_return_t ret = DDS_RETCODE_OK; dds__retcode_t rc; struct dds_reader * rd; @@ -137,7 +137,7 @@ dds_read_impl( goto fail; } if (hand != DDS_HANDLE_NIL) { - if (dds_tkmap_find_by_id(gv.m_tkmap, hand) == NULL) { + if (ddsi_tkmap_find_by_id(gv.m_tkmap, hand) == NULL) { DDS_ERROR("Could not find instance\n"); ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET); dds_read_unlock(rd, cond); @@ -146,28 +146,24 @@ dds_read_impl( } /* Allocate samples if not provided (assuming all or none provided) */ if (buf[0] == NULL) { - char * loan; - const size_t sz = rd->m_topic->m_descriptor->m_size; - const uint32_t loan_size = (uint32_t) (sz * maxs); /* Allocate, use or reallocate loan cached on reader */ if (rd->m_loan_out) { - loan = dds_alloc (loan_size); + ddsi_sertopic_realloc_samples (buf, rd->m_topic->m_stopic, NULL, 0, maxs); } else { if (rd->m_loan) { - if (rd->m_loan_size < loan_size) { - rd->m_loan = dds_realloc_zero (rd->m_loan, loan_size); - rd->m_loan_size = loan_size; + if (rd->m_loan_size < maxs) { + ddsi_sertopic_realloc_samples (buf, rd->m_topic->m_stopic, rd->m_loan, rd->m_loan_size, maxs); + rd->m_loan = buf[0]; + rd->m_loan_size = maxs; + } else { + buf[0] = rd->m_loan; } } else { - rd->m_loan = dds_alloc (loan_size); - rd->m_loan_size = loan_size; + ddsi_sertopic_realloc_samples (buf, rd->m_topic->m_stopic, NULL, 0, maxs); + rd->m_loan = buf[0]; + rd->m_loan_size = maxs; } - loan = rd->m_loan; - rd->m_loan_out = true; - } - for (i = 0; i < maxs; i++) { - buf[i] = loan; - loan += sz; + rd->m_loan_out = true; } } if (take) { @@ -759,7 +755,7 @@ dds_return_loan( _In_ int32_t bufsz) { dds__retcode_t rc; - const dds_topic_descriptor_t * desc; + const struct ddsi_sertopic *st; dds_reader *rd; dds_readcond *cond; dds_return_t ret = DDS_RETCODE_OK; @@ -781,20 +777,16 @@ dds_return_loan( ret = DDS_ERRNO(rc); goto fail; } - desc = rd->m_topic->m_descriptor; + st = rd->m_topic->m_stopic; - /* Only free sample contents if they have been allocated */ - if (desc->m_flagset & DDS_TOPIC_NO_OPTIMIZE) { - int32_t i = 0; - for (i = 0; i < bufsz; i++) { - dds_sample_free(buf[i], desc, DDS_FREE_CONTENTS); - } + for (int32_t i = 0; i < bufsz; i++) { + ddsi_sertopic_free_sample (st, buf[i], DDS_FREE_CONTENTS); } /* If possible return loan buffer to reader */ if (rd->m_loan != 0 && (buf[0] == rd->m_loan)) { rd->m_loan_out = false; - memset (rd->m_loan, 0, rd->m_loan_size); + ddsi_sertopic_zero_samples (st, rd->m_loan, rd->m_loan_size); buf[0] = NULL; } 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 72e4260..012435f 100644 --- a/src/core/ddsc/src/dds_rhc.c +++ b/src/core/ddsc/src/dds_rhc.c @@ -24,7 +24,7 @@ #include "dds__entity.h" #include "dds__reader.h" #include "dds__rhc.h" -#include "dds__tkmap.h" +#include "ddsi/ddsi_tkmap.h" #include "util/ut_hopscotch.h" #include "util/ut_avl.h" @@ -253,7 +253,7 @@ struct rhc_instance nn_wctime_t tstamp; /* source time stamp of last update */ struct rhc_instance *next; /* next non-empty instance in arbitrary ordering */ struct rhc_instance *prev; - struct tkmap_instance *tk; /* backref into TK for unref'ing */ + struct ddsi_tkmap_instance *tk; /* backref into TK for unref'ing */ struct rhc_sample a_sample; /* pre-allocated storage for 1 sample */ }; @@ -504,7 +504,7 @@ static void free_instance (void *vnode, void *varg) { remove_inst_from_nonempty_list (rhc, inst); } - dds_tkmap_instance_unref (inst->tk); + ddsi_tkmap_instance_unref (inst->tk); dds_free (inst); } @@ -668,8 +668,7 @@ static bool content_filter_accepts (const struct ddsi_sertopic *sertopic, const const struct dds_topic *tp = sertopic->status_cb_entity; if (tp->filter_fn) { - const dds_topic_descriptor_t * desc = tp->m_descriptor; - char *tmp = dds_alloc (desc->m_size); + char *tmp = ddsi_sertopic_alloc_sample (tp->m_stopic); ddsi_serdata_to_sample (sample, tmp, NULL, NULL); ret = (tp->filter_fn) (tmp, tp->filter_ctx); ddsi_sertopic_free_sample (tp->m_stopic, tmp, DDS_FREE_ALL); @@ -1023,12 +1022,12 @@ static struct rhc_instance * alloc_new_instance ( const struct proxy_writer_info *pwr_info, struct ddsi_serdata *serdata, - struct tkmap_instance *tk + struct ddsi_tkmap_instance *tk ) { struct rhc_instance *inst; - dds_tkmap_instance_ref (tk); + ddsi_tkmap_instance_ref (tk); inst = dds_alloc (sizeof (*inst)); inst->iid = tk->m_iid; inst->tk = tk; @@ -1052,7 +1051,7 @@ static rhc_store_result_t rhc_store_new_instance struct rhc *rhc, const struct proxy_writer_info *pwr_info, struct ddsi_serdata *sample, - struct tkmap_instance *tk, + struct ddsi_tkmap_instance *tk, const bool has_data, status_cb_data_t * cb_data ) @@ -1124,7 +1123,7 @@ static rhc_store_result_t rhc_store_new_instance bool dds_rhc_store ( struct rhc * __restrict rhc, const struct proxy_writer_info * __restrict pwr_info, - struct ddsi_serdata * __restrict sample, struct tkmap_instance * __restrict tk + struct ddsi_serdata * __restrict sample, struct ddsi_tkmap_instance * __restrict tk ) { const uint64_t wr_iid = pwr_info->iid; @@ -1402,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; @@ -2168,7 +2175,6 @@ static bool update_conditions_locked dds_readcond * iter; int m_pre; int m_post; - const struct dds_topic_descriptor *desc = rhc->topic->status_cb_entity->m_descriptor; char *tmp = NULL; DDS_TRACE("update_conditions_locked(%p) - inst %u nonempty %u disp %u nowr %u new %u samples %u read %u\n", @@ -2214,8 +2220,7 @@ static bool update_conditions_locked { if (sample && tmp == NULL && (dds_entity_kind(iter->m_entity.m_hdl) == DDS_KIND_COND_QUERY)) { - tmp = os_malloc (desc->m_size); - memset (tmp, 0, desc->m_size); + tmp = ddsi_sertopic_alloc_sample (rhc->topic); ddsi_serdata_to_sample (sample, tmp, NULL, NULL); } if @@ -2251,8 +2256,7 @@ static bool update_conditions_locked if (tmp) { - ddsi_sertopic_free_sample (rhc->topic, tmp, DDS_FREE_CONTENTS); - os_free (tmp); + ddsi_sertopic_free_sample (rhc->topic, tmp, DDS_FREE_ALL); } return trigger; } diff --git a/src/core/ddsc/src/dds_topic.c b/src/core/ddsc/src/dds_topic.c index 5e88b9d..bd4774a 100644 --- a/src/core/ddsc/src/dds_topic.c +++ b/src/core/ddsc/src/dds_topic.c @@ -24,7 +24,7 @@ #include "ddsi/ddsi_sertopic.h" #include "ddsi/q_ddsi_discovery.h" #include "os/os_atomics.h" -#include "dds__iid.h" +#include "ddsi/ddsi_iid.h" #define DDS_TOPIC_STATUS_MASK \ DDS_INCONSISTENT_TOPIC_STATUS @@ -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( @@ -322,31 +316,42 @@ static bool dupdef_qos_ok(const dds_qos_t *qos, const struct ddsi_sertopic *st) } } +static bool sertopic_equivalent (const struct ddsi_sertopic *a, const struct ddsi_sertopic *b) +{ + printf ("sertopic_equivalent %p %p (%s %s; %u %u; %p %p; %p %p)\n", a, b, a->name_typename, b->name_typename, a->serdata_basehash, b->serdata_basehash, a->ops, b->ops, a->serdata_ops, b->serdata_ops); + + if (strcmp (a->name_typename, b->name_typename) != 0) + return false; + if (a->serdata_basehash != b->serdata_basehash) + return false; + if (a->ops != b->ops) + return false; + if (a->serdata_ops != b->serdata_ops) + return false; + return true; +} + _Pre_satisfies_((participant & DDS_ENTITY_KIND_MASK) == DDS_KIND_PARTICIPANT) DDS_EXPORT dds_entity_t -dds_create_topic( +dds_create_topic_arbitrary ( _In_ dds_entity_t participant, - _In_ const dds_topic_descriptor_t *desc, + _In_ struct ddsi_sertopic *sertopic, _In_z_ const char *name, _In_opt_ const dds_qos_t *qos, - _In_opt_ const dds_listener_t *listener) + _In_opt_ const dds_listener_t *listener, + _In_opt_ const nn_plist_t *sedp_plist) { - char *key = NULL; struct ddsi_sertopic *stgeneric; - struct ddsi_sertopic_default *st; - const char *typename; dds__retcode_t rc; dds_entity *par; dds_topic *top; dds_qos_t *new_qos = NULL; - nn_plist_t plist; dds_entity_t hdl; struct participant *ddsi_pp; struct thread_state1 *const thr = lookup_thread_state (); const bool asleep = !vtime_awake_p (thr->vtime); - uint32_t index; - if (desc == NULL){ + if (sertopic == NULL){ DDS_ERROR("Topic description is NULL\n"); hdl = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER); goto bad_param_err; @@ -384,8 +389,7 @@ dds_create_topic( /* Check if topic already exists with same name */ os_mutexLock (&dds_global.m_mutex); if ((stgeneric = dds_topic_lookup_locked (par->m_domain, name)) != NULL) { - st = (struct ddsi_sertopic_default *)stgeneric; - if (st->type != desc) { + if (!sertopic_equivalent (stgeneric,sertopic)) { /* FIXME: should copy the type, perhaps? but then the pointers will no longer be the same */ DDS_ERROR("Create topic with mismatching type\n"); hdl = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET); @@ -394,17 +398,11 @@ dds_create_topic( DDS_ERROR("Create topic with mismatching qos\n"); hdl = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY); } else { - dds_entity_add_ref (&st->c.status_cb_entity->m_entity); - hdl = st->c.status_cb_entity->m_entity.m_hdl; + dds_entity_add_ref (&stgeneric->status_cb_entity->m_entity); + hdl = stgeneric->status_cb_entity->m_entity.m_hdl; } os_mutexUnlock (&dds_global.m_mutex); } else { - typename = desc->m_typename; - key = (char*) dds_alloc (strlen (name) + strlen (typename) + 2); - strcpy (key, name); - strcat (key, "/"); - strcat (key, typename); - if (qos) { new_qos = dds_create_qos(); /* Only returns failure when one of the qos args is NULL, which @@ -414,77 +412,29 @@ dds_create_topic( /* Create topic */ top = dds_alloc (sizeof (*top)); - top->m_descriptor = desc; hdl = dds_entity_init (&top->m_entity, par, DDS_KIND_TOPIC, new_qos, listener, DDS_TOPIC_STATUS_MASK); top->m_entity.m_deriver.delete = dds_topic_delete; top->m_entity.m_deriver.set_qos = dds_topic_qos_set; top->m_entity.m_deriver.validate_status = dds_topic_status_validate; - - st = dds_alloc (sizeof (*st)); - - os_atomic_st32 (&st->c.refc, 1); - st->c.iid = dds_iid_gen (); - st->c.status_cb = dds_topic_status_cb; - st->c.status_cb_entity = top; - st->c.name_typename = key; - st->c.name = dds_alloc (strlen (name) + 1); - strcpy (st->c.name, name); - st->c.typename = dds_alloc (strlen (typename) + 1); - strcpy (st->c.typename, typename); - st->c.ops = &ddsi_sertopic_ops_default; - st->c.serdata_ops = desc->m_nkeys ? &ddsi_serdata_ops_cdr : &ddsi_serdata_ops_cdr_nokey; - st->c.serdata_basehash = ddsi_sertopic_compute_serdata_basehash (st->c.serdata_ops); - st->native_encoding_identifier = (PLATFORM_IS_LITTLE_ENDIAN ? CDR_LE : CDR_BE); - - st->type = (void*) desc; - st->nkeys = desc->m_nkeys; - st->keys = desc->m_keys; - - /* Check if topic cannot be optimised (memcpy marshal) */ - - if ((desc->m_flagset & DDS_TOPIC_NO_OPTIMIZE) == 0) { - st->opt_size = dds_stream_check_optimize (desc); - } - top->m_stopic = &st->c; + top->m_stopic = ddsi_sertopic_ref (sertopic); + sertopic->status_cb_entity = top; /* Add topic to extent */ - dds_topic_add_locked (par->m_domainid, &st->c); + dds_topic_add_locked (par->m_domainid, sertopic); os_mutexUnlock (&dds_global.m_mutex); - nn_plist_init_empty (&plist); - if (new_qos) { - dds_merge_qos (&plist.qos, new_qos); - } - - /* Set Topic meta data (for SEDP publication) */ - plist.qos.topic_name = dds_string_dup (st->c.name); - plist.qos.type_name = dds_string_dup (st->c.typename); - plist.qos.present |= (QP_TOPIC_NAME | QP_TYPE_NAME); - if (desc->m_meta) { - plist.type_description = dds_string_dup (desc->m_meta); - plist.present |= PP_PRISMTECH_TYPE_DESCRIPTION; - } - if (desc->m_nkeys) { - plist.qos.present |= QP_PRISMTECH_SUBSCRIPTION_KEYS; - plist.qos.subscription_keys.use_key_list = 1; - plist.qos.subscription_keys.key_list.n = desc->m_nkeys; - plist.qos.subscription_keys.key_list.strs = dds_alloc (desc->m_nkeys * sizeof (char*)); - for (index = 0; index < desc->m_nkeys; index++) { - plist.qos.subscription_keys.key_list.strs[index] = dds_string_dup (desc->m_keys[index].m_name); - } - } - /* Publish Topic */ if (asleep) { thread_state_awake (thr); } ddsi_pp = ephash_lookup_participant_guid (&par->m_guid); assert (ddsi_pp); - sedp_write_topic (ddsi_pp, &plist); + if (sedp_plist) { + sedp_write_topic (ddsi_pp, sedp_plist); + } if (asleep) { thread_state_asleep (thr); } - nn_plist_fini (&plist); } qos_err: @@ -494,6 +444,103 @@ bad_param_err: return hdl; } +_Pre_satisfies_((participant & DDS_ENTITY_KIND_MASK) == DDS_KIND_PARTICIPANT) +DDS_EXPORT dds_entity_t +dds_create_topic( + _In_ dds_entity_t participant, + _In_ const dds_topic_descriptor_t *desc, + _In_z_ const char *name, + _In_opt_ const dds_qos_t *qos, + _In_opt_ const dds_listener_t *listener) +{ + char *key = NULL; + struct ddsi_sertopic_default *st; + const char *typename; + dds_qos_t *new_qos = NULL; + nn_plist_t plist; + dds_entity_t hdl; + uint32_t index; + + if (desc == NULL){ + DDS_ERROR("Topic description is NULL"); + hdl = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER); + goto bad_param_err; + } + + if (name == NULL) { + DDS_ERROR("Topic name is NULL"); + hdl = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER); + goto bad_param_err; + } + + if (!is_valid_name(name)) { + DDS_ERROR("Topic name contains characters that are not allowed."); + hdl = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER); + goto bad_param_err; + } + + typename = desc->m_typename; + key = (char*) dds_alloc (strlen (name) + strlen (typename) + 2); + strcpy (key, name); + strcat (key, "/"); + strcat (key, typename); + + st = dds_alloc (sizeof (*st)); + + os_atomic_st32 (&st->c.refc, 1); + st->c.iid = ddsi_iid_gen (); + st->c.status_cb = dds_topic_status_cb; + st->c.status_cb_entity = NULL; /* set by dds_create_topic_arbitrary */ + st->c.name_typename = key; + st->c.name = dds_alloc (strlen (name) + 1); + strcpy (st->c.name, name); + st->c.typename = dds_alloc (strlen (typename) + 1); + strcpy (st->c.typename, typename); + st->c.ops = &ddsi_sertopic_ops_default; + st->c.serdata_ops = desc->m_nkeys ? &ddsi_serdata_ops_cdr : &ddsi_serdata_ops_cdr_nokey; + st->c.serdata_basehash = ddsi_sertopic_compute_serdata_basehash (st->c.serdata_ops); + st->native_encoding_identifier = (PLATFORM_IS_LITTLE_ENDIAN ? CDR_LE : CDR_BE); + + st->type = (void*) desc; + st->nkeys = desc->m_nkeys; + st->keys = desc->m_keys; + + /* Check if topic cannot be optimised (memcpy marshal) */ + if ((desc->m_flagset & DDS_TOPIC_NO_OPTIMIZE) == 0) { + st->opt_size = dds_stream_check_optimize (desc); + } + + nn_plist_init_empty (&plist); + if (new_qos) { + dds_merge_qos (&plist.qos, new_qos); + } + + /* Set Topic meta data (for SEDP publication) */ + plist.qos.topic_name = dds_string_dup (st->c.name); + plist.qos.type_name = dds_string_dup (st->c.typename); + plist.qos.present |= (QP_TOPIC_NAME | QP_TYPE_NAME); + if (desc->m_meta) { + plist.type_description = dds_string_dup (desc->m_meta); + plist.present |= PP_PRISMTECH_TYPE_DESCRIPTION; + } + if (desc->m_nkeys) { + plist.qos.present |= QP_PRISMTECH_SUBSCRIPTION_KEYS; + plist.qos.subscription_keys.use_key_list = 1; + plist.qos.subscription_keys.key_list.n = desc->m_nkeys; + plist.qos.subscription_keys.key_list.strs = dds_alloc (desc->m_nkeys * sizeof (char*)); + for (index = 0; index < desc->m_nkeys; index++) { + plist.qos.subscription_keys.key_list.strs[index] = dds_string_dup (desc->m_keys[index].m_name); + } + } + + hdl = dds_create_topic_arbitrary(participant, &st->c, name, qos, listener, &plist); + ddsi_sertopic_unref (&st->c); + nn_plist_fini (&plist); + +bad_param_err: + return hdl; +} + static bool dds_topic_chaining_filter( const void *sample, diff --git a/src/core/ddsc/src/dds_whc.c b/src/core/ddsc/src/dds_whc.c index c1dca65..1f02d62 100644 --- a/src/core/ddsc/src/dds_whc.c +++ b/src/core/ddsc/src/dds_whc.c @@ -18,7 +18,7 @@ #include "ddsi/q_unused.h" #include "ddsi/q_config.h" #include "dds__whc.h" -#include "dds__tkmap.h" +#include "ddsi/ddsi_tkmap.h" #include "util/ut_avl.h" #include "util/ut_hopscotch.h" @@ -55,7 +55,7 @@ struct whc_intvnode { struct whc_idxnode { uint64_t iid; seqno_t prune_seq; - struct tkmap_instance *tk; + struct ddsi_tkmap_instance *tk; unsigned headidx; #if __STDC_VERSION__ >= 199901L struct whc_node *hist[]; @@ -128,7 +128,7 @@ static unsigned whc_default_remove_acked_messages_full (struct whc_impl *whc, se static unsigned whc_default_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list); static void whc_default_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list); static void whc_default_get_state(const struct whc *whc, struct whc_state *st); -static int whc_default_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk); +static int whc_default_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk); static seqno_t whc_default_next_seq (const struct whc *whc, seqno_t seq); static bool whc_default_borrow_sample (const struct whc *whc, seqno_t seq, struct whc_borrowed_sample *sample); static bool whc_default_borrow_sample_key (const struct whc *whc, const struct ddsi_serdata *serdata_key, struct whc_borrowed_sample *sample); @@ -324,7 +324,7 @@ static struct whc_node *whc_findkey (const struct whc_impl *whc, const struct dd } template; struct whc_idxnode *n; check_whc (whc); - template.idxn.iid = dds_tkmap_lookup(gv.m_tkmap, serdata_key); + template.idxn.iid = ddsi_tkmap_lookup(gv.m_tkmap, serdata_key); n = ut_hhLookup (whc->idx_hash, &template.idxn); if (n == NULL) return NULL; @@ -537,7 +537,7 @@ static void delete_one_sample_from_idx (struct whc_impl *whc, struct whc_node *w #endif if (!ut_hhRemove (whc->idx_hash, idxn)) assert (0); - dds_tkmap_instance_unref(idxn->tk); + ddsi_tkmap_instance_unref(idxn->tk); os_free (idxn); } whcn->idxnode = NULL; @@ -1081,7 +1081,7 @@ static struct whc_node *whc_default_insert_seq (struct whc_impl *whc, seqno_t ma return newn; } -static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk) +static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk) { struct whc_impl * const whc = (struct whc_impl *)whc_generic; struct whc_node *newn = NULL; @@ -1190,7 +1190,7 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se unsigned i; idxn = os_malloc (sizeof (*idxn) + whc->idxdepth * sizeof (idxn->hist[0])); DDS_LOG(DDS_LC_WHC, " idxn %p", (void *)idxn); - dds_tkmap_instance_ref(tk); + ddsi_tkmap_instance_ref(tk); idxn->iid = tk->m_iid; idxn->tk = tk; idxn->prune_seq = 0; diff --git a/src/core/ddsc/src/dds_write.c b/src/core/ddsc/src/dds_write.c index f0fe316..73e5f4d 100644 --- a/src/core/ddsc/src/dds_write.c +++ b/src/core/ddsc/src/dds_write.c @@ -13,7 +13,7 @@ #include #include "dds__writer.h" #include "dds__write.h" -#include "dds__tkmap.h" +#include "ddsi/ddsi_tkmap.h" #include "ddsi/q_error.h" #include "ddsi/q_thread.h" #include "ddsi/q_xmsg.h" @@ -115,7 +115,7 @@ static int deliver_locally( _In_ struct writer *wr, _In_ struct ddsi_serdata *payload, - _In_ struct tkmap_instance *tk) + _In_ struct ddsi_tkmap_instance *tk) { dds_return_t ret = DDS_RETCODE_OK; os_mutexLock (&wr->rdary.rdary_lock); @@ -193,7 +193,7 @@ dds_write_impl( const bool writekey = action & DDS_WR_KEY_BIT; dds_writer * writer = (dds_writer*) wr; struct writer * ddsi_wr = writer->m_wr; - struct tkmap_instance * tk; + struct ddsi_tkmap_instance * tk; struct ddsi_serdata *d; if (data == NULL) { @@ -220,7 +220,7 @@ dds_write_impl( ((action & DDS_WR_UNREGISTER_BIT) ? NN_STATUSINFO_UNREGISTER : 0) ; d->timestamp.v = tstamp; ddsi_serdata_ref(d); - tk = (ddsi_plugin.rhc_plugin.rhc_lookup_fn) (d); + tk = ddsi_tkmap_lookup_instance_ref(d); w_rc = write_sample_gc (writer->m_xp, ddsi_wr, d, tk); if (w_rc >= 0) { @@ -243,7 +243,7 @@ dds_write_impl( ret = deliver_locally (ddsi_wr, d, tk); } ddsi_serdata_unref(d); - (ddsi_plugin.rhc_plugin.rhc_unref_fn) (tk); + ddsi_tkmap_instance_unref(tk); if (asleep) { thread_state_asleep (thr); @@ -267,7 +267,7 @@ dds_writecdr_impl( struct thread_state1 * const thr = lookup_thread_state (); const bool asleep = !vtime_awake_p (thr->vtime); struct writer * ddsi_wr = wr->m_wr; - struct tkmap_instance * tk; + struct ddsi_tkmap_instance * tk; if (wr->m_topic->filter_fn) { abort(); @@ -283,7 +283,7 @@ dds_writecdr_impl( ((action & DDS_WR_UNREGISTER_BIT) ? NN_STATUSINFO_UNREGISTER : 0) ; d->timestamp.v = tstamp; ddsi_serdata_ref(d); - tk = (ddsi_plugin.rhc_plugin.rhc_lookup_fn) (d); + tk = ddsi_tkmap_lookup_instance_ref(d); w_rc = write_sample_gc (wr->m_xp, ddsi_wr, d, tk); if (w_rc >= 0) { /* Flush out write unless configured to batch */ @@ -306,7 +306,7 @@ dds_writecdr_impl( ret = deliver_locally (ddsi_wr, d, tk); } ddsi_serdata_unref(d); - (ddsi_plugin.rhc_plugin.rhc_unref_fn) (tk); + ddsi_tkmap_instance_unref(tk); if (asleep) { thread_state_asleep (thr); diff --git a/src/core/ddsc/src/dds_writer.c b/src/core/ddsc/src/dds_writer.c index 3e9f1fe..4a958e6 100644 --- a/src/core/ddsc/src/dds_writer.c +++ b/src/core/ddsc/src/dds_writer.c @@ -20,7 +20,7 @@ #include "dds__qos.h" #include "dds__err.h" #include "dds__init.h" -#include "dds__tkmap.h" +#include "ddsi/ddsi_tkmap.h" #include "dds__whc.h" #include "ddsc/ddsc_project.h" 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 039c4a6..75d3af7 100644 --- a/src/core/ddsi/CMakeLists.txt +++ b/src/core/ddsi/CMakeLists.txt @@ -20,14 +20,17 @@ PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src" ddsi_mcgroup.c ddsi_serdata.c ddsi_serdata_default.c + ddsi_serdata_builtin.c ddsi_sertopic.c ddsi_sertopic_default.c + ddsi_sertopic_builtin.c ddsi_rhc_plugin.c + ddsi_iid.c + ddsi_tkmap.c q_addrset.c 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 @@ -73,7 +76,10 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/ddsi" ddsi_serdata.h ddsi_sertopic.h ddsi_serdata_default.h + ddsi_serdata_builtin.h ddsi_rhc_plugin.h + ddsi_iid.h + ddsi_tkmap.h probes-constants.h q_addrset.h q_align.h @@ -81,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/ddsc/src/dds__iid.h b/src/core/ddsi/include/ddsi/ddsi_iid.h similarity index 69% rename from src/core/ddsc/src/dds__iid.h rename to src/core/ddsi/include/ddsi/ddsi_iid.h index b7134d4..a5b9528 100644 --- a/src/core/ddsc/src/dds__iid.h +++ b/src/core/ddsi/include/ddsi/ddsi_iid.h @@ -12,15 +12,25 @@ #ifndef _DDS_IID_H_ #define _DDS_IID_H_ -#include "dds__types.h" +#include "os/os.h" #if defined (__cplusplus) extern "C" { #endif -void dds_iid_init (void); -void dds_iid_fini (void); -uint64_t dds_iid_gen (void); +struct ddsi_iid { +#if OS_ATOMIC64_SUPPORT + os_atomic_uint64_t counter; +#else + os_mutex lock; + uint64_t counter; +#endif + uint32_t key[4]; +}; + +void ddsi_iid_init (void); +void ddsi_iid_fini (void); +uint64_t ddsi_iid_gen (void); #if defined (__cplusplus) } diff --git a/src/core/ddsi/include/ddsi/ddsi_rhc_plugin.h b/src/core/ddsi/include/ddsi/ddsi_rhc_plugin.h index ba378a3..0516e89 100644 --- a/src/core/ddsi/include/ddsi/ddsi_rhc_plugin.h +++ b/src/core/ddsi/include/ddsi/ddsi_rhc_plugin.h @@ -14,7 +14,7 @@ struct rhc; struct nn_xqos; -struct tkmap_instance; +struct ddsi_tkmap_instance; struct ddsi_serdata; struct ddsi_sertopic; struct entity_common; @@ -33,14 +33,12 @@ struct ddsi_rhc_plugin void (*rhc_fini_fn) (struct rhc *rhc); bool (*rhc_store_fn) (struct rhc * __restrict rhc, const struct proxy_writer_info * __restrict pwr_info, - struct ddsi_serdata * __restrict sample, struct tkmap_instance * __restrict tk); + struct ddsi_serdata * __restrict sample, struct ddsi_tkmap_instance * __restrict tk); void (*rhc_unregister_wr_fn) (struct rhc * __restrict rhc, const struct proxy_writer_info * __restrict pwr_info); void (*rhc_relinquish_ownership_fn) (struct rhc * __restrict rhc, const uint64_t wr_iid); void (*rhc_set_qos_fn) (struct rhc * rhc, const struct nn_xqos * qos); - struct tkmap_instance * (*rhc_lookup_fn) (struct ddsi_serdata *serdata); - void (*rhc_unref_fn) (struct tkmap_instance *tk); }; void make_proxy_writer_info(struct proxy_writer_info *pwr_info, const struct entity_common *e, const struct nn_xqos *xqos); diff --git a/src/core/ddsi/include/ddsi/ddsi_serdata_builtin.h b/src/core/ddsi/include/ddsi/ddsi_serdata_builtin.h new file mode 100644 index 0000000..3770378 --- /dev/null +++ b/src/core/ddsi/include/ddsi/ddsi_serdata_builtin.h @@ -0,0 +1,44 @@ +/* + * 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 DDSI_SERDATA_BUILTIN_H +#define DDSI_SERDATA_BUILTIN_H + +#include "os/os.h" +#include "util/ut_avl.h" +#include "sysdeps.h" +#include "ddsi/ddsi_serdata.h" +#include "ddsi/ddsi_sertopic.h" +#include "ddsi/q_xqos.h" + +struct ddsi_serdata_builtin { + struct ddsi_serdata c; + nn_guid_t key; + nn_xqos_t xqos; +}; + +enum ddsi_sertopic_builtin_type { + DSBT_PARTICIPANT, + DSBT_READER, + DSBT_WRITER +}; + +struct ddsi_sertopic_builtin { + struct ddsi_sertopic c; + enum ddsi_sertopic_builtin_type type; +}; + +extern const struct ddsi_sertopic_ops ddsi_sertopic_ops_builtin; +extern const struct ddsi_serdata_ops ddsi_serdata_ops_builtin; + +struct ddsi_sertopic *new_sertopic_builtin (enum ddsi_sertopic_builtin_type type, const char *name, const char *typename); + +#endif diff --git a/src/core/ddsi/include/ddsi/ddsi_serdata_default.h b/src/core/ddsi/include/ddsi/ddsi_serdata_default.h index 5614ff1..b9328fb 100644 --- a/src/core/ddsi/include/ddsi/ddsi_serdata_default.h +++ b/src/core/ddsi/include/ddsi/ddsi_serdata_default.h @@ -9,8 +9,8 @@ * * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause */ -#ifndef DDSI_SER_H -#define DDSI_SER_H +#ifndef DDSI_SERDATA_DEFAULT_H +#define DDSI_SERDATA_DEFAULT_H #include "os/os.h" #include "ddsi/q_plist.h" /* for nn_prismtech_writer_info */ diff --git a/src/core/ddsi/include/ddsi/ddsi_sertopic.h b/src/core/ddsi/include/ddsi/ddsi_sertopic.h index fe1d68f..d400245 100644 --- a/src/core/ddsi/include/ddsi/ddsi_sertopic.h +++ b/src/core/ddsi/include/ddsi/ddsi_sertopic.h @@ -41,11 +41,19 @@ struct ddsi_sertopic { typedef void (*ddsi_sertopic_deinit_t) (struct ddsi_sertopic *tp); /* Release any memory allocated by ddsi_sertopic_to_sample */ -typedef void (*ddsi_sertopic_free_sample_t) (const struct ddsi_sertopic *d, void *sample, dds_free_op_t op); +typedef void (*ddsi_sertopic_zero_samples_t) (const struct ddsi_sertopic *d, void *samples, size_t count); + +/* Release any memory allocated by ddsi_sertopic_to_sample */ +typedef void (*ddsi_sertopic_realloc_samples_t) (void **ptrs, const struct ddsi_sertopic *d, void *old, size_t oldcount, size_t count); + +/* Release any memory allocated by ddsi_sertopic_to_sample (also undo sertopic_alloc_sample if "op" so requests) */ +typedef void (*ddsi_sertopic_free_samples_t) (const struct ddsi_sertopic *d, void **ptrs, size_t count, dds_free_op_t op); struct ddsi_sertopic_ops { ddsi_sertopic_deinit_t deinit; - ddsi_sertopic_free_sample_t free_sample; + ddsi_sertopic_zero_samples_t zero_samples; + ddsi_sertopic_realloc_samples_t realloc_samples; + ddsi_sertopic_free_samples_t free_samples; }; struct ddsi_sertopic *ddsi_sertopic_ref (const struct ddsi_sertopic *tp); @@ -55,8 +63,26 @@ uint32_t ddsi_sertopic_compute_serdata_basehash (const struct ddsi_serdata_ops * inline void ddsi_sertopic_deinit (struct ddsi_sertopic *tp) { tp->ops->deinit (tp); } +inline void ddsi_sertopic_zero_samples (const struct ddsi_sertopic *tp, void *samples, size_t count) { + tp->ops->zero_samples (tp, samples, count); +} +inline void ddsi_sertopic_realloc_samples (void **ptrs, const struct ddsi_sertopic *tp, void *old, size_t oldcount, size_t count) +{ + tp->ops->realloc_samples (ptrs, tp, old, oldcount, count); +} +inline void ddsi_sertopic_free_samples (const struct ddsi_sertopic *tp, void **ptrs, size_t count, dds_free_op_t op) { + tp->ops->free_samples (tp, ptrs, count, op); +} +inline void ddsi_sertopic_zero_sample (const struct ddsi_sertopic *tp, void *sample) { + ddsi_sertopic_zero_samples (tp, sample, 1); +} +inline void *ddsi_sertopic_alloc_sample (const struct ddsi_sertopic *tp) { + void *ptr; + ddsi_sertopic_realloc_samples (&ptr, tp, NULL, 0, 1); + return ptr; +} inline void ddsi_sertopic_free_sample (const struct ddsi_sertopic *tp, void *sample, dds_free_op_t op) { - tp->ops->free_sample (tp, sample, op); + ddsi_sertopic_free_samples (tp, &sample, 1, op); } #endif diff --git a/src/core/ddsi/include/ddsi/ddsi_tkmap.h b/src/core/ddsi/include/ddsi/ddsi_tkmap.h new file mode 100644 index 0000000..82cc825 --- /dev/null +++ b/src/core/ddsi/include/ddsi/ddsi_tkmap.h @@ -0,0 +1,52 @@ +/* + * 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 _DDS_TKMAP_H_ +#define _DDS_TKMAP_H_ + +#include "dds__types.h" +#include "os/os_atomics.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +struct ddsi_tkmap; +struct ddsi_serdata; +struct dds_topic; + +struct ddsi_tkmap_instance +{ + struct ddsi_serdata * m_sample; + struct ddsi_tkmap * m_map; + uint64_t m_iid; + os_atomic_uint32_t m_refc; +}; + + +struct ddsi_tkmap * ddsi_tkmap_new (void); +void ddsi_tkmap_free (_Inout_ _Post_invalid_ struct ddsi_tkmap *tkmap); +void ddsi_tkmap_instance_ref (_In_ struct ddsi_tkmap_instance *tk); +uint64_t ddsi_tkmap_lookup (_In_ struct ddsi_tkmap *tkmap, _In_ const struct ddsi_serdata *serdata); +_Check_return_ bool ddsi_tkmap_get_key (_In_ struct ddsi_tkmap * map, const struct ddsi_sertopic *topic, _In_ uint64_t iid, _Out_ void * sample); +_Check_return_ struct ddsi_tkmap_instance * ddsi_tkmap_find( + _In_ struct ddsi_serdata * sd, + _In_ const bool rd, + _In_ const bool create); +_Check_return_ struct ddsi_tkmap_instance * ddsi_tkmap_find_by_id (_In_ struct ddsi_tkmap * map, _In_ uint64_t iid); + +DDS_EXPORT _Check_return_ struct ddsi_tkmap_instance * ddsi_tkmap_lookup_instance_ref (_In_ struct ddsi_serdata * sd); +DDS_EXPORT void ddsi_tkmap_instance_unref (_In_ struct ddsi_tkmap_instance * tk); + +#if defined (__cplusplus) +} +#endif +#endif 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 087b685..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,13 +412,10 @@ 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; - - /* IID generator */ - - uint64_t (*iidgen_fn) (void); }; extern struct config OSAPI_EXPORT config; diff --git a/src/core/ddsi/include/ddsi/q_ephash.h b/src/core/ddsi/include/ddsi/q_ephash.h index 43863ce..3779d00 100644 --- a/src/core/ddsi/include/ddsi/q_ephash.h +++ b/src/core/ddsi/include/ddsi/q_ephash.h @@ -80,6 +80,7 @@ void ephash_remove_reader_guid (struct reader *rd); void ephash_remove_proxy_writer_guid (struct proxy_writer *pwr); void ephash_remove_proxy_reader_guid (struct proxy_reader *prd); +void *ephash_lookup_guid_untyped (const struct nn_guid *guid); void *ephash_lookup_guid (const struct nn_guid *guid, enum entity_kind kind); struct participant *ephash_lookup_participant_guid (const struct nn_guid *guid); diff --git a/src/core/ddsi/include/ddsi/q_globals.h b/src/core/ddsi/include/ddsi/q_globals.h index 91a2123..c91a029 100644 --- a/src/core/ddsi/include/ddsi/q_globals.h +++ b/src/core/ddsi/include/ddsi/q_globals.h @@ -18,11 +18,11 @@ #include "util/ut_fibheap.h" - #include "ddsi/q_plist.h" #include "ddsi/q_protocol.h" #include "ddsi/q_nwif.h" #include "ddsi/q_sockwaitset.h" +#include "ddsi/ddsi_iid.h" #ifdef DDSI_INCLUDE_ENCRYPTION #include "ddsi/q_security.h" /* for q_securityDecoderSet */ @@ -47,7 +47,7 @@ struct ddsi_tran_listener; struct ddsi_tran_factory; struct ut_thread_pool_s; struct debug_monitor; -struct tkmap; +struct ddsi_tkmap; typedef struct ospl_in_addr_node { nn_locator_t loc; @@ -90,7 +90,8 @@ struct q_globals { volatile int deaf; volatile int mute; - struct tkmap * m_tkmap; + struct ddsi_tkmap * m_tkmap; + struct ddsi_iid dds_iid; /* Hash tables for participants, readers, writers, proxy participants, proxy readers and proxy writers by GUID @@ -280,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/include/ddsi/q_transmit.h b/src/core/ddsi/include/ddsi/q_transmit.h index 7573592..1f87abd 100644 --- a/src/core/ddsi/include/ddsi/q_transmit.h +++ b/src/core/ddsi/include/ddsi/q_transmit.h @@ -25,7 +25,7 @@ struct writer; struct whc_state; struct proxy_reader; struct ddsi_serdata; -struct tkmap_instance; +struct ddsi_tkmap_instance; /* Writing new data; serdata_twrite (serdata) is assumed to be really recentish; serdata is unref'd. If xp == NULL, data is queued, else @@ -34,8 +34,8 @@ struct tkmap_instance; "nogc": no GC may occur, so it may not block to throttle the writer if the high water mark of the WHC is reached, which implies true KEEP_LAST behaviour. This is true for all the DDSI built-in writers. "gc": GC may occur, which means the writer history and watermarks can be anything. This must be used for all application data. */ -int write_sample_gc (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata, struct tkmap_instance *tk); -int write_sample_nogc (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata, struct tkmap_instance *tk); +int write_sample_gc (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk); +int write_sample_nogc (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk); int write_sample_gc_notk (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata); int write_sample_nogc_notk (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata); diff --git a/src/core/ddsi/include/ddsi/q_whc.h b/src/core/ddsi/include/ddsi/q_whc.h index 1a99e65..f5bc549 100644 --- a/src/core/ddsi/include/ddsi/q_whc.h +++ b/src/core/ddsi/include/ddsi/q_whc.h @@ -18,7 +18,7 @@ extern "C" { struct ddsi_serdata; struct nn_plist; -struct tkmap_instance; +struct ddsi_tkmap_instance; struct whc_node; /* opaque, but currently used for deferred free lists */ struct whc; @@ -70,7 +70,7 @@ typedef void (*whc_free_t)(struct whc *whc); reliable readers that have not acknowledged all data */ /* max_drop_seq must go soon, it's way too ugly. */ /* plist may be NULL or os_malloc'd, WHC takes ownership of plist */ -typedef int (*whc_insert_t)(struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk); +typedef int (*whc_insert_t)(struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk); typedef unsigned (*whc_downgrade_to_volatile_t)(struct whc *whc, struct whc_state *st); typedef unsigned (*whc_remove_acked_messages_t)(struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list); typedef void (*whc_free_deferred_free_list_t)(struct whc *whc, struct whc_node *deferred_free_list); @@ -118,7 +118,7 @@ inline bool whc_sample_iter_borrow_next (struct whc_sample_iter *it, struct whc_ inline void whc_free (struct whc *whc) { whc->ops->free (whc); } -inline int whc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk) { +inline int whc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk) { return whc->ops->insert (whc, max_drop_seq, seq, plist, serdata, tk); } inline unsigned whc_downgrade_to_volatile (struct whc *whc, struct whc_state *st) { diff --git a/src/core/ddsc/src/dds_iid.c b/src/core/ddsi/src/ddsi_iid.c similarity index 69% rename from src/core/ddsc/src/dds_iid.c rename to src/core/ddsi/src/ddsi_iid.c index 1809dd8..d8c092d 100644 --- a/src/core/ddsc/src/dds_iid.c +++ b/src/core/ddsi/src/ddsi_iid.c @@ -9,13 +9,10 @@ * * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause */ -#include "dds__iid.h" +#include "ddsi/ddsi_iid.h" #include "ddsi/q_time.h" #include "ddsi/q_globals.h" -static os_mutex dds_iid_lock_g; -static dds_iid dds_iid_g; - static void dds_tea_encrypt (uint32_t v[2], const uint32_t k[4]) { /* TEA encryption straight from Wikipedia */ @@ -43,37 +40,50 @@ static void dds_tea_decrypt (uint32_t v[2], const uint32_t k[4]) v[0]=v0; v[1]=v1; } -uint64_t dds_iid_gen (void) +uint64_t ddsi_iid_gen (void) { uint64_t iid; union { uint64_t u64; uint32_t u32[2]; } tmp; - os_mutexLock (&dds_iid_lock_g); - tmp.u64 = ++dds_iid_g.counter; - dds_tea_encrypt (tmp.u32, dds_iid_g.key); +#if OS_ATOMIC64_SUPPORT + tmp.u64 = os_atomic_inc64_nv (&gv.dds_iid.counter); +#else + os_mutexLock (&gv.dds_iid.lock); + tmp.u64 = ++gv.dds_iid.counter; + os_mutexUnlock (&gv.dds_iid.lock); +#endif + + dds_tea_encrypt (tmp.u32, gv.dds_iid.key); iid = tmp.u64; - os_mutexUnlock (&dds_iid_lock_g); return iid; } -void dds_iid_init (void) +void ddsi_iid_init (void) { union { uint64_t u64; uint32_t u32[2]; } tmp; nn_wctime_t tnow = now (); - os_mutexInit (&dds_iid_lock_g); +#if ! OS_ATOMIC64_SUPPORT + os_mutexInit (&gv.dds_iid.lock); +#endif - dds_iid_g.key[0] = (uint32_t) ((uintptr_t) &dds_iid_g); - dds_iid_g.key[1] = (uint32_t) tnow.v; - dds_iid_g.key[2] = (uint32_t) (tnow.v >> 32); - dds_iid_g.key[3] = 0xdeadbeef; + gv.dds_iid.key[0] = (uint32_t) os_procIdSelf(); + gv.dds_iid.key[1] = (uint32_t) tnow.v; + gv.dds_iid.key[2] = (uint32_t) (tnow.v >> 32); + gv.dds_iid.key[3] = 0xdeadbeef; tmp.u64 = 0; - dds_tea_decrypt (tmp.u32, dds_iid_g.key); - dds_iid_g.counter = tmp.u64; + dds_tea_decrypt (tmp.u32, gv.dds_iid.key); +#if OS_ATOMIC64_SUPPORT + os_atomic_st64 (&gv.dds_iid.counter, tmp.u64); +#else + gv.dds_iid.counter = tmp.u64; +#endif } -void dds_iid_fini (void) +void ddsi_iid_fini (void) { - os_mutexDestroy (&dds_iid_lock_g); +#if ! OS_ATOMIC64_SUPPORT + os_mutexDestroy (&gv.dds_iid.lock); +#endif } diff --git a/src/core/ddsi/src/ddsi_serdata_builtin.c b/src/core/ddsi/src/ddsi_serdata_builtin.c new file mode 100644 index 0000000..a61bffe --- /dev/null +++ b/src/core/ddsi/src/ddsi_serdata_builtin.c @@ -0,0 +1,287 @@ +/* + * 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 +#include + +#include "os/os.h" +#include "ddsi/sysdeps.h" +#include "ddsi/q_md5.h" +#include "ddsi/q_bswap.h" +#include "ddsi/q_config.h" +#include "ddsi/q_freelist.h" +#include +#include +#include "os/os.h" +#include "dds__key.h" +#include "ddsi/ddsi_tkmap.h" +#include "dds__stream.h" +#include "ddsi/q_entity.h" +#include "ddsi/ddsi_serdata_builtin.h" +//#include "dds.h" /* FIXME: need the sample types of the built-in topics */ + +static const uint64_t unihashconsts[] = { + UINT64_C (16292676669999574021), + UINT64_C (10242350189706880077), + UINT64_C (12844332200329132887), + UINT64_C (16728792139623414127) +}; + +static uint32_t hash_guid (const nn_guid_t *g) +{ + return + (uint32_t) (((((uint32_t) g->prefix.u[0] + unihashconsts[0]) * + ((uint32_t) g->prefix.u[1] + unihashconsts[1])) + + (((uint32_t) g->prefix.u[2] + unihashconsts[2]) * + ((uint32_t) g->entityid.u + unihashconsts[3]))) + >> 32); +} + +static struct ddsi_serdata *fix_serdata_builtin(struct ddsi_serdata_builtin *d, uint32_t basehash) +{ + d->c.hash = hash_guid (&d->key) ^ basehash; + return &d->c; +} + +static bool serdata_builtin_eqkey(const struct ddsi_serdata *acmn, const struct ddsi_serdata *bcmn) +{ + const struct ddsi_serdata_builtin *a = (const struct ddsi_serdata_builtin *)acmn; + const struct ddsi_serdata_builtin *b = (const struct ddsi_serdata_builtin *)bcmn; + return memcmp (&a->key, &b->key, sizeof (a->key)) == 0; +} + +static void serdata_builtin_free(struct ddsi_serdata *dcmn) +{ + struct ddsi_serdata_builtin *d = (struct ddsi_serdata_builtin *)dcmn; + if (d->c.kind == SDK_DATA) + nn_xqos_fini (&d->xqos); + os_free (d); +} + +static struct ddsi_serdata_builtin *serdata_builtin_new(const struct ddsi_sertopic_builtin *tp, enum ddsi_serdata_kind kind) +{ + struct ddsi_serdata_builtin *d = os_malloc(sizeof (*d)); + ddsi_serdata_init (&d->c, &tp->c, kind); + return d; +} + +static void from_entity_pp (struct ddsi_serdata_builtin *d, const struct participant *pp) +{ + nn_xqos_copy(&d->xqos, &pp->plist->qos); +} + +static void from_entity_proxypp (struct ddsi_serdata_builtin *d, const struct proxy_participant *proxypp) +{ + nn_xqos_copy(&d->xqos, &proxypp->plist->qos); +} + +static void set_topic_type_from_sertopic (struct ddsi_serdata_builtin *d, const struct ddsi_sertopic *tp) +{ + if (!(d->xqos.present & QP_TOPIC_NAME)) + { + d->xqos.topic_name = dds_string_dup (tp->name); + d->xqos.present |= QP_TOPIC_NAME; + } + if (!(d->xqos.present & QP_TYPE_NAME)) + { + d->xqos.type_name = dds_string_dup (tp->typename); + d->xqos.present |= QP_TYPE_NAME; + } +} + +static void from_entity_rd (struct ddsi_serdata_builtin *d, const struct reader *rd) +{ + nn_xqos_copy(&d->xqos, rd->xqos); + set_topic_type_from_sertopic(d, rd->topic); +} + +static void from_entity_prd (struct ddsi_serdata_builtin *d, const struct proxy_reader *prd) +{ + nn_xqos_copy(&d->xqos, prd->c.xqos); + assert (d->xqos.present & QP_TOPIC_NAME); + assert (d->xqos.present & QP_TYPE_NAME); +} + +static void from_entity_wr (struct ddsi_serdata_builtin *d, const struct writer *wr) +{ + nn_xqos_copy(&d->xqos, wr->xqos); + set_topic_type_from_sertopic(d, wr->topic); +} + +static void from_entity_pwr (struct ddsi_serdata_builtin *d, const struct proxy_writer *pwr) +{ + nn_xqos_copy(&d->xqos, pwr->c.xqos); + assert (d->xqos.present & QP_TOPIC_NAME); + assert (d->xqos.present & QP_TYPE_NAME); +} + +struct ddsi_serdata *ddsi_serdata_builtin_from_keyhash (const struct ddsi_sertopic *tpcmn, const nn_keyhash_t *keyhash) +{ + /* FIXME: not quite elegant to manage the creation of a serdata for a built-in topic via this function, but I also find it quite unelegant to let from_sample read straight from the underlying internal entity, and to_sample convert to the external format ... I could claim the internal entity is the "serialised form", but that forces wrapping it in a fragchain in one way or another, which, though possible, is also a bit lacking in elegance. */ + const struct ddsi_sertopic_builtin *tp = (const struct ddsi_sertopic_builtin *)tpcmn; + /* keyhash must in host format (which the GUIDs always are internally) */ + const struct entity_common *entity = ephash_lookup_guid_untyped ((const nn_guid_t *) keyhash->value); + struct ddsi_serdata_builtin *d = serdata_builtin_new(tp, entity ? SDK_DATA : SDK_KEY); + memcpy (&d->key, keyhash->value, sizeof (d->key)); + if (d->c.kind == SDK_DATA) + { + switch (entity->kind) + { + case EK_PARTICIPANT: + assert (tp->type == DSBT_PARTICIPANT); + from_entity_pp (d, (const struct participant *) entity); + break; + case EK_READER: + assert (tp->type == DSBT_READER); + from_entity_rd (d, (const struct reader *) entity); + break; + case EK_WRITER: + assert (tp->type == DSBT_WRITER); + from_entity_wr (d, (const struct writer *) entity); + break; + case EK_PROXY_PARTICIPANT: + assert (tp->type == DSBT_PARTICIPANT); + from_entity_proxypp (d, (const struct proxy_participant *) entity); + break; + case EK_PROXY_READER: + assert (tp->type == DSBT_READER); + from_entity_prd (d, (const struct proxy_reader *) entity); + break; + case EK_PROXY_WRITER: + assert (tp->type == DSBT_WRITER); + from_entity_pwr (d, (const struct proxy_writer *) entity); + break; + } + } + return fix_serdata_builtin(d, tp->c.serdata_basehash); +} + +static struct ddsi_serdata *serdata_builtin_to_topicless (const struct ddsi_serdata *serdata_common) +{ + /* All built-in ones are currently topicless */ + return ddsi_serdata_ref (serdata_common); +} + +static void convkey (dds_builtintopic_guid_t *key, const nn_guid_t *guid) +{ + nn_guid_t tmp; + tmp = nn_hton_guid (*guid); + memcpy (key, &tmp, sizeof (*key)); +} + +static char *dds_string_dup_reuse (char *old, const char *src) +{ + size_t size = strlen (src) + 1; + char *new = dds_realloc(old, size); + return memcpy (new, src, size); +} + +static dds_qos_t *dds_qos_from_xqos_reuse (dds_qos_t *old, const nn_xqos_t *src) +{ + if (old == NULL) + return nn_xqos_dup (src); + else + { + nn_xqos_fini (old); + nn_xqos_mergein_missing (old, src); + return old; + } +} + +static bool to_sample_pp (const struct ddsi_serdata_builtin *d, struct dds_builtintopic_participant *sample) +{ + convkey (&sample->key, &d->key); + if (d->c.kind == SDK_DATA) + { + sample->qos = dds_qos_from_xqos_reuse (sample->qos, &d->xqos); + } + return true; +} + +static bool to_sample_endpoint (const struct ddsi_serdata_builtin *d, struct dds_builtintopic_endpoint *sample) +{ + nn_guid_t ppguid; + convkey (&sample->key, &d->key); + ppguid = d->key; + ppguid.entityid.u = NN_ENTITYID_PARTICIPANT; + convkey (&sample->participant_key, &ppguid); + if (d->c.kind == SDK_DATA) + { + assert (d->xqos.present & QP_TOPIC_NAME); + assert (d->xqos.present & QP_TYPE_NAME); + sample->topic_name = dds_string_dup_reuse (sample->topic_name, d->xqos.topic_name); + sample->type_name = dds_string_dup_reuse (sample->type_name, d->xqos.type_name); + sample->qos = dds_qos_from_xqos_reuse (sample->qos, &d->xqos); + } + return true; +} + +static bool serdata_builtin_topicless_to_sample (const struct ddsi_sertopic *topic, const struct ddsi_serdata *serdata_common, void *sample, void **bufptr, void *buflim) +{ + const struct ddsi_serdata_builtin *d = (const struct ddsi_serdata_builtin *)serdata_common; + const struct ddsi_sertopic_builtin *tp = (const struct ddsi_sertopic_builtin *)topic; + if (bufptr) abort(); else { (void)buflim; } /* FIXME: haven't implemented that bit yet! */ + /* FIXME: completing builtin topic support along these lines requires subscribers, publishers and topics to also become DDSI entities - which is probably a good thing anyway */ + switch (tp->type) + { + case DSBT_PARTICIPANT: + return to_sample_pp (d, sample); + case DSBT_READER: + case DSBT_WRITER: + return to_sample_endpoint (d, sample); + } + assert (0); + return false; +} + +static bool serdata_builtin_to_sample (const struct ddsi_serdata *serdata_common, void *sample, void **bufptr, void *buflim) +{ + return serdata_builtin_topicless_to_sample (serdata_common->topic, serdata_common, sample, bufptr, buflim); +} + +static uint32_t serdata_builtin_get_size (const struct ddsi_serdata *serdata_common) +{ + (void)serdata_common; + return 0; +} + +static void serdata_builtin_to_ser (const struct ddsi_serdata *serdata_common, size_t off, size_t sz, void *buf) +{ + (void)serdata_common; (void)off; (void)sz; (void)buf; +} + +static struct ddsi_serdata *serdata_builtin_to_ser_ref (const struct ddsi_serdata *serdata_common, size_t off, size_t sz, ddsi_iovec_t *ref) +{ + (void)serdata_common; (void)off; (void)sz; (void)ref; + return NULL; +} + +static void serdata_builtin_to_ser_unref (struct ddsi_serdata *serdata_common, const ddsi_iovec_t *ref) +{ + (void)serdata_common; (void)ref; +} + +const struct ddsi_serdata_ops ddsi_serdata_ops_builtin = { + .get_size = serdata_builtin_get_size, + .eqkey = serdata_builtin_eqkey, + .free = serdata_builtin_free, + .from_ser = 0, + .from_keyhash = ddsi_serdata_builtin_from_keyhash, + .from_sample = 0, + .to_ser = serdata_builtin_to_ser, + .to_sample = serdata_builtin_to_sample, + .to_ser_ref = serdata_builtin_to_ser_ref, + .to_ser_unref = serdata_builtin_to_ser_unref, + .to_topicless = serdata_builtin_to_topicless, + .topicless_to_sample = serdata_builtin_topicless_to_sample +}; diff --git a/src/core/ddsi/src/ddsi_serdata_default.c b/src/core/ddsi/src/ddsi_serdata_default.c index 548a92e..1373474 100644 --- a/src/core/ddsi/src/ddsi_serdata_default.c +++ b/src/core/ddsi/src/ddsi_serdata_default.c @@ -24,7 +24,7 @@ #include #include "os/os.h" #include "dds__key.h" -#include "dds__tkmap.h" +#include "ddsi/ddsi_tkmap.h" #include "dds__stream.h" #include "ddsi/q_radmin.h" #include "ddsi/ddsi_serdata_default.h" @@ -53,9 +53,9 @@ static void serdata_free_wrap (void *elem) { #ifndef NDEBUG struct ddsi_serdata_default *d = elem; - assert(os_atomic_ld32(&d->c.refc) == 1); + assert(os_atomic_ld32(&d->c.refc) == 0); #endif - ddsi_serdata_unref(elem); + dds_free(elem); } void ddsi_serdatapool_free (struct serdatapool * pool) @@ -200,7 +200,9 @@ static bool serdata_default_eqkey_nokey (const struct ddsi_serdata *acmn, const static void serdata_default_free(struct ddsi_serdata *dcmn) { struct ddsi_serdata_default *d = (struct ddsi_serdata_default *)dcmn; - dds_free (d); + assert(os_atomic_ld32(&d->c.refc) == 0); + if (!nn_freelist_push (&gv.serpool->freelist, d)) + dds_free (d); } static void serdata_default_init(struct ddsi_serdata_default *d, const struct ddsi_sertopic_default *tp, enum ddsi_serdata_kind kind) @@ -231,6 +233,8 @@ static struct ddsi_serdata_default *serdata_default_new(const struct ddsi_sertop struct ddsi_serdata_default *d; if ((d = nn_freelist_pop (&gv.serpool->freelist)) == NULL) d = serdata_default_allocnew(gv.serpool); + else + os_atomic_st32(&d->c.refc, 1); serdata_default_init(d, tp, kind); return d; } diff --git a/src/core/ddsi/src/ddsi_sertopic.c b/src/core/ddsi/src/ddsi_sertopic.c index 3a5687b..c4d71db 100644 --- a/src/core/ddsi/src/ddsi_sertopic.c +++ b/src/core/ddsi/src/ddsi_sertopic.c @@ -61,4 +61,9 @@ uint32_t ddsi_sertopic_compute_serdata_basehash (const struct ddsi_serdata_ops * } extern inline void ddsi_sertopic_deinit (struct ddsi_sertopic *tp); +extern inline void ddsi_sertopic_zero_samples (const struct ddsi_sertopic *tp, void *samples, size_t count); +extern inline void ddsi_sertopic_realloc_samples (void **ptrs, const struct ddsi_sertopic *tp, void *old, size_t oldcount, size_t count); +extern inline void ddsi_sertopic_free_samples (const struct ddsi_sertopic *tp, void **ptrs, size_t count, dds_free_op_t op); +extern inline void ddsi_sertopic_zero_sample (const struct ddsi_sertopic *tp, void *sample); extern inline void ddsi_sertopic_free_sample (const struct ddsi_sertopic *tp, void *sample, dds_free_op_t op); +extern inline void *ddsi_sertopic_alloc_sample (const struct ddsi_sertopic *tp); diff --git a/src/core/ddsi/src/ddsi_sertopic_builtin.c b/src/core/ddsi/src/ddsi_sertopic_builtin.c new file mode 100644 index 0000000..31d2263 --- /dev/null +++ b/src/core/ddsi/src/ddsi_sertopic_builtin.c @@ -0,0 +1,147 @@ +/* + * 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 +#include + +#include "os/os.h" +#include "ddsi/sysdeps.h" +#include "ddsi/q_md5.h" +#include "ddsi/q_bswap.h" +#include "ddsi/q_config.h" +#include "ddsi/q_freelist.h" +#include "ddsi/ddsi_sertopic.h" +#include "ddsi/ddsi_serdata_builtin.h" +#include "ddsc/dds.h" + +/* FIXME: sertopic /= ddstopic so a lot of stuff needs to be moved here from dds_topic.c and the free function needs to be implemented properly */ + +struct ddsi_sertopic *new_sertopic_builtin (enum ddsi_sertopic_builtin_type type, const char *name, const char *typename) +{ + struct ddsi_sertopic_builtin *tp = os_malloc (sizeof (*tp)); + tp->c.iid = ddsi_iid_gen(); + tp->c.name = dds_string_dup (name); + tp->c.typename = dds_string_dup (typename); + const size_t name_typename_size = strlen (tp->c.name) + 1 + strlen (tp->c.typename) + 1; + tp->c.name_typename = dds_alloc (name_typename_size); + snprintf (tp->c.name_typename, name_typename_size, "%s/%s", tp->c.name, tp->c.typename); + tp->c.ops = &ddsi_sertopic_ops_builtin; + tp->c.serdata_ops = &ddsi_serdata_ops_builtin; + tp->c.serdata_basehash = ddsi_sertopic_compute_serdata_basehash (tp->c.serdata_ops); + tp->c.status_cb = 0; + tp->c.status_cb_entity = NULL; + os_atomic_st32 (&tp->c.refc, 1); + tp->type = type; + return &tp->c; +} + +static void sertopic_builtin_deinit (struct ddsi_sertopic *tp) +{ + (void)tp; +} + +static void free_pp (void *vsample) +{ + dds_builtintopic_participant_t *sample = vsample; + dds_delete_qos (sample->qos); + sample->qos = NULL; +} + +static void free_endpoint (void *vsample) +{ + dds_builtintopic_endpoint_t *sample = vsample; + dds_free (sample->topic_name); + dds_free (sample->type_name); + dds_delete_qos (sample->qos); + sample->topic_name = sample->type_name = NULL; + sample->qos = NULL; +} + +static size_t get_size (enum ddsi_sertopic_builtin_type type) +{ + switch (type) + { + case DSBT_PARTICIPANT: + return sizeof (dds_builtintopic_participant_t); + case DSBT_READER: + case DSBT_WRITER: + return sizeof (dds_builtintopic_endpoint_t); + } + assert (0); + return 0; +} + +static void sertopic_builtin_zero_samples (const struct ddsi_sertopic *sertopic_common, void *samples, size_t count) +{ + const struct ddsi_sertopic_builtin *tp = (const struct ddsi_sertopic_builtin *)sertopic_common; + size_t size = get_size (tp->type); + memset (samples, 0, size * count); +} + +static void sertopic_builtin_realloc_samples (void **ptrs, const struct ddsi_sertopic *sertopic_common, void *old, size_t oldcount, size_t count) +{ + const struct ddsi_sertopic_builtin *tp = (const struct ddsi_sertopic_builtin *)sertopic_common; + const size_t size = get_size (tp->type); + char *new = dds_realloc (old, size * count); + if (new && count > oldcount) + memset (new + size * oldcount, 0, size * (count - oldcount)); + for (size_t i = 0; i < count; i++) + { + void *ptr = (char *) new + i * size; + ptrs[i] = ptr; + } +} + +static void sertopic_builtin_free_samples (const struct ddsi_sertopic *sertopic_common, void **ptrs, size_t count, dds_free_op_t op) +{ + if (count > 0) + { + const struct ddsi_sertopic_builtin *tp = (const struct ddsi_sertopic_builtin *)sertopic_common; + const size_t size = get_size (tp->type); +#ifndef NDEBUG + for (size_t i = 0, off = 0; i < count; i++, off += size) + assert ((char *)ptrs[i] == (char *)ptrs[0] + off); +#endif + if (op & DDS_FREE_CONTENTS_BIT) + { + void (*f) (void *); + char *ptr = ptrs[0]; + switch (tp->type) + { + case DSBT_PARTICIPANT: + f = free_pp; + break; + case DSBT_READER: + case DSBT_WRITER: + f = free_endpoint; + break; + } + for (size_t i = 0; i < count; i++) + { + f (ptr); + ptr += size; + } + } + if (op & DDS_FREE_ALL_BIT) + { + dds_free (ptrs[0]); + } + } +} + +const struct ddsi_sertopic_ops ddsi_sertopic_ops_builtin = { + .deinit = sertopic_builtin_deinit, + .zero_samples = sertopic_builtin_zero_samples, + .realloc_samples = sertopic_builtin_realloc_samples, + .free_samples = sertopic_builtin_free_samples +}; diff --git a/src/core/ddsi/src/ddsi_sertopic_default.c b/src/core/ddsi/src/ddsi_sertopic_default.c index e906d26..8afddb0 100644 --- a/src/core/ddsi/src/ddsi_sertopic_default.c +++ b/src/core/ddsi/src/ddsi_sertopic_default.c @@ -30,13 +30,56 @@ static void sertopic_default_deinit (struct ddsi_sertopic *tp) (void)tp; } -static void sertopic_default_free_sample (const struct ddsi_sertopic *sertopic_common, void *sample, dds_free_op_t op) +static void sertopic_default_zero_samples (const struct ddsi_sertopic *sertopic_common, void *sample, size_t count) { const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)sertopic_common; - dds_sample_free (sample, tp->type, op); + memset (sample, 0, tp->type->m_size * count); +} + +static void sertopic_default_realloc_samples (void **ptrs, const struct ddsi_sertopic *sertopic_common, void *old, size_t oldcount, size_t count) +{ + const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)sertopic_common; + const size_t size = tp->type->m_size; + char *new = dds_realloc (old, size * count); + if (new && count > oldcount) + memset (new + size * oldcount, 0, size * (count - oldcount)); + for (size_t i = 0; i < count; i++) + { + void *ptr = (char *) new + i * size; + ptrs[i] = ptr; + } +} + +static void sertopic_default_free_samples (const struct ddsi_sertopic *sertopic_common, void **ptrs, size_t count, dds_free_op_t op) +{ + if (count > 0) + { + const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)sertopic_common; + const struct dds_topic_descriptor *type = tp->type; + const size_t size = type->m_size; +#ifndef NDEBUG + for (size_t i = 0, off = 0; i < count; i++, off += size) + assert ((char *)ptrs[i] == (char *)ptrs[0] + off); +#endif + if (type->m_flagset & DDS_TOPIC_NO_OPTIMIZE) + { + char *ptr = ptrs[0]; + for (size_t i = 0; i < count; i++) + { + dds_sample_free (ptr, type, DDS_FREE_CONTENTS); + ptr += size; + } + } + if (op & DDS_FREE_ALL_BIT) + { + dds_free (ptrs[0]); + } + } } const struct ddsi_sertopic_ops ddsi_sertopic_ops_default = { .deinit = sertopic_default_deinit, - .free_sample = sertopic_default_free_sample + .zero_samples = sertopic_default_zero_samples, + .realloc_samples = sertopic_default_realloc_samples, + .free_samples = sertopic_default_free_samples }; diff --git a/src/core/ddsc/src/dds_tkmap.c b/src/core/ddsi/src/ddsi_tkmap.c similarity index 78% rename from src/core/ddsc/src/dds_tkmap.c rename to src/core/ddsi/src/ddsi_tkmap.c index 951ede2..089aaf5 100644 --- a/src/core/ddsc/src/dds_tkmap.c +++ b/src/core/ddsi/src/ddsi_tkmap.c @@ -17,8 +17,8 @@ #include "ddsi/q_globals.h" #include "ddsi/q_config.h" #include "ddsi/sysdeps.h" -#include "dds__tkmap.h" -#include "dds__iid.h" +#include "ddsi/ddsi_iid.h" +#include "ddsi/ddsi_tkmap.h" #include "util/ut_hopscotch.h" #include "dds__stream.h" #include "os/os.h" @@ -27,7 +27,7 @@ #define REFC_DELETE 0x80000000 #define REFC_MASK 0x0fffffff -struct tkmap +struct ddsi_tkmap { struct ut_chh * m_hh; os_mutex m_lock; @@ -49,20 +49,20 @@ static void gc_buckets (void *a) static void gc_tkmap_instance_impl (struct gcreq *gcreq) { - struct tkmap_instance *tk = gcreq->arg; + struct ddsi_tkmap_instance *tk = gcreq->arg; ddsi_serdata_unref (tk->m_sample); dds_free (tk); gcreq_free (gcreq); } -static void gc_tkmap_instance (struct tkmap_instance *tk) +static void gc_tkmap_instance (struct ddsi_tkmap_instance *tk) { struct gcreq *gcreq = gcreq_new (gv.gcreq_queue, gc_tkmap_instance_impl); gcreq->arg = tk; gcreq_enqueue (gcreq); } -static uint32_t dds_tk_hash (const struct tkmap_instance * inst) +static uint32_t dds_tk_hash (const struct ddsi_tkmap_instance * inst) { return inst->m_sample->hash; } @@ -72,7 +72,7 @@ static uint32_t dds_tk_hash_void (const void * inst) return dds_tk_hash (inst); } -static int dds_tk_equals (const struct tkmap_instance *a, const struct tkmap_instance *b) +static int dds_tk_equals (const struct ddsi_tkmap_instance *a, const struct ddsi_tkmap_instance *b) { return (a->m_sample->ops == b->m_sample->ops) ? ddsi_serdata_eqkey (a->m_sample, b->m_sample) : 0; } @@ -82,9 +82,9 @@ static int dds_tk_equals_void (const void *a, const void *b) return dds_tk_equals (a, b); } -struct tkmap * dds_tkmap_new (void) +struct ddsi_tkmap * ddsi_tkmap_new (void) { - struct tkmap *tkmap = dds_alloc (sizeof (*tkmap)); + struct ddsi_tkmap *tkmap = dds_alloc (sizeof (*tkmap)); tkmap->m_hh = ut_chhNew (1, dds_tk_hash_void, dds_tk_equals_void, gc_buckets); os_mutexInit (&tkmap->m_lock); os_condInit (&tkmap->m_cond, &tkmap->m_lock); @@ -93,12 +93,12 @@ struct tkmap * dds_tkmap_new (void) static void free_tkmap_instance (void *vtk, UNUSED_ARG(void *f_arg)) { - struct tkmap_instance *tk = vtk; + struct ddsi_tkmap_instance *tk = vtk; ddsi_serdata_unref (tk->m_sample); os_free (tk); } -void dds_tkmap_free (_Inout_ _Post_invalid_ struct tkmap * map) +void ddsi_tkmap_free (_Inout_ _Post_invalid_ struct ddsi_tkmap * map) { ut_chhEnumUnsafe (map->m_hh, free_tkmap_instance, NULL); ut_chhFree (map->m_hh); @@ -107,10 +107,10 @@ void dds_tkmap_free (_Inout_ _Post_invalid_ struct tkmap * map) dds_free (map); } -uint64_t dds_tkmap_lookup (_In_ struct tkmap * map, _In_ const struct ddsi_serdata * sd) +uint64_t ddsi_tkmap_lookup (_In_ struct ddsi_tkmap * map, _In_ const struct ddsi_serdata * sd) { - struct tkmap_instance dummy; - struct tkmap_instance * tk; + struct ddsi_tkmap_instance dummy; + struct ddsi_tkmap_instance * tk; dummy.m_sample = (struct ddsi_serdata *) sd; tk = ut_chhLookup (map->m_hh, &dummy); return (tk) ? tk->m_iid : DDS_HANDLE_NIL; @@ -127,7 +127,7 @@ tkmap_get_key_arg; static void dds_tkmap_get_key_fn (void * vtk, void * varg) { - struct tkmap_instance * tk = vtk; + struct ddsi_tkmap_instance * tk = vtk; tkmap_get_key_arg * arg = (tkmap_get_key_arg*) varg; if (tk->m_iid == arg->m_iid) { @@ -137,7 +137,7 @@ static void dds_tkmap_get_key_fn (void * vtk, void * varg) } _Check_return_ -bool dds_tkmap_get_key (_In_ struct tkmap * map, const struct ddsi_sertopic *topic, _In_ uint64_t iid, _Out_ void * sample) +bool ddsi_tkmap_get_key (_In_ struct ddsi_tkmap * map, const struct ddsi_sertopic *topic, _In_ uint64_t iid, _Out_ void * sample) { tkmap_get_key_arg arg = { topic, iid, sample, false }; os_mutexLock (&map->m_lock); @@ -149,13 +149,13 @@ bool dds_tkmap_get_key (_In_ struct tkmap * map, const struct ddsi_sertopic *top typedef struct { uint64_t m_iid; - struct tkmap_instance * m_inst; + struct ddsi_tkmap_instance * m_inst; } tkmap_get_inst_arg; static void dds_tkmap_get_inst_fn (void * vtk, void * varg) { - struct tkmap_instance * tk = vtk; + struct ddsi_tkmap_instance * tk = vtk; tkmap_get_inst_arg * arg = (tkmap_get_inst_arg*) varg; if (tk->m_iid == arg->m_iid) { @@ -164,7 +164,7 @@ static void dds_tkmap_get_inst_fn (void * vtk, void * varg) } _Check_return_ -struct tkmap_instance * dds_tkmap_find_by_id (_In_ struct tkmap * map, _In_ uint64_t iid) +struct ddsi_tkmap_instance * ddsi_tkmap_find_by_id (_In_ struct ddsi_tkmap * map, _In_ uint64_t iid) { tkmap_get_inst_arg arg = { iid, NULL }; ut_chhEnumUnsafe (map->m_hh, dds_tkmap_get_inst_fn, &arg); @@ -184,14 +184,14 @@ struct tkmap_instance * dds_tkmap_find_by_id (_In_ struct tkmap * map, _In_ uint #endif _Check_return_ -struct tkmap_instance * dds_tkmap_find( +struct ddsi_tkmap_instance * ddsi_tkmap_find( _In_ struct ddsi_serdata * sd, _In_ const bool rd, _In_ const bool create) { - struct tkmap_instance dummy; - struct tkmap_instance * tk; - struct tkmap * map = gv.m_tkmap; + struct ddsi_tkmap_instance dummy; + struct ddsi_tkmap_instance * tk; + struct ddsi_tkmap * map = gv.m_tkmap; dummy.m_sample = sd; retry: @@ -222,7 +222,7 @@ retry: tk->m_sample = ddsi_serdata_to_topicless (sd); tk->m_map = map; os_atomic_st32 (&tk->m_refc, 1); - tk->m_iid = dds_iid_gen (); + tk->m_iid = ddsi_iid_gen (); if (!ut_chhAdd (map->m_hh, tk)) { /* Lost a race from another thread, retry */ @@ -240,18 +240,18 @@ retry: } _Check_return_ -struct tkmap_instance * dds_tkmap_lookup_instance_ref (_In_ struct ddsi_serdata * sd) +struct ddsi_tkmap_instance * ddsi_tkmap_lookup_instance_ref (_In_ struct ddsi_serdata * sd) { assert (vtime_awake_p (lookup_thread_state ()->vtime)); - return dds_tkmap_find (sd, true, true); + return ddsi_tkmap_find (sd, true, true); } -void dds_tkmap_instance_ref (_In_ struct tkmap_instance *tk) +void ddsi_tkmap_instance_ref (_In_ struct ddsi_tkmap_instance *tk) { os_atomic_inc32 (&tk->m_refc); } -void dds_tkmap_instance_unref (_In_ struct tkmap_instance * tk) +void ddsi_tkmap_instance_unref (_In_ struct ddsi_tkmap_instance * tk) { uint32_t old, new; assert (vtime_awake_p(lookup_thread_state()->vtime)); @@ -267,7 +267,7 @@ void dds_tkmap_instance_unref (_In_ struct tkmap_instance * tk) } while (!os_atomic_cas32(&tk->m_refc, old, new)); if (new == REFC_DELETE) { - struct tkmap *map = tk->m_map; + struct ddsi_tkmap *map = tk->m_map; /* Remove from hash table */ int removed = ut_chhRemove(map->m_hh, tk); 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 ae487e1..1ca70c5 100644 --- a/src/core/ddsi/src/q_entity.c +++ b/src/core/ddsi/src/q_entity.c @@ -35,13 +35,14 @@ #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" #include "ddsi/sysdeps.h" #include "dds__whc.h" +#include "ddsi/ddsi_iid.h" +#include "ddsi/ddsi_tkmap.h" struct deleted_participant { ut_avlNode_t avlnode; @@ -153,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_plugin.iidgen_fn) (); - 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) @@ -221,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) @@ -357,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); @@ -399,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; @@ -578,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 @@ -604,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; } @@ -813,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); @@ -1613,9 +1658,10 @@ static void writer_add_local_connection (struct writer *wr, struct reader *rd) struct proxy_writer_info pwr_info; struct ddsi_serdata *payload = sample.serdata; /* FIXME: whc has tk reference in its index nodes, which is what we really should be iterating over anyway, and so we don't really have to look them up anymore */ - struct tkmap_instance *tk = (ddsi_plugin.rhc_plugin.rhc_lookup_fn) (payload); + struct ddsi_tkmap_instance *tk = ddsi_tkmap_lookup_instance_ref(payload); make_proxy_writer_info(&pwr_info, &wr->e, wr->xqos); (void)(ddsi_plugin.rhc_plugin.rhc_store_fn) (rd->rhc, &pwr_info, payload, tk); + ddsi_tkmap_instance_unref(tk); } } @@ -2330,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) { @@ -2560,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); @@ -2572,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; @@ -2781,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) @@ -2906,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); @@ -3122,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); @@ -3130,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)); @@ -3234,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; } @@ -3326,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; @@ -3401,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); @@ -3410,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; @@ -3566,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); } @@ -3592,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; } @@ -3845,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); @@ -3979,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; @@ -3990,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 */ @@ -4024,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); @@ -4035,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; @@ -4101,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; @@ -4232,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); @@ -4249,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)); @@ -4261,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 @@ -4275,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; } @@ -4357,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_ephash.c b/src/core/ddsi/src/q_ephash.c index 571d933..88cb373 100644 --- a/src/core/ddsi/src/q_ephash.c +++ b/src/core/ddsi/src/q_ephash.c @@ -116,15 +116,19 @@ static void ephash_guid_remove (struct entity_common *e) assert (x); } -static void *ephash_lookup_guid_int (const struct ephash *ephash, const struct nn_guid *guid, enum entity_kind kind) +void *ephash_lookup_guid_untyped (const struct nn_guid *guid) { /* FIXME: could (now) require guid to be first in entity_common; entity_common already is first in entity */ struct entity_common e; + e.guid = *guid; + return ut_chhLookup (gv.guid_hash->hash, &e); +} + +static void *ephash_lookup_guid_int (const struct ephash *ephash, const struct nn_guid *guid, enum entity_kind kind) +{ struct entity_common *res; (void)ephash; - e.guid = *guid; - res = ut_chhLookup (gv.guid_hash->hash, &e); - if (res && res->kind == kind) + if ((res = ephash_lookup_guid_untyped (guid)) != NULL && res->kind == kind) return res; else return NULL; @@ -132,7 +136,7 @@ static void *ephash_lookup_guid_int (const struct ephash *ephash, const struct n void *ephash_lookup_guid (const struct nn_guid *guid, enum entity_kind kind) { - return ephash_lookup_guid_int (gv.guid_hash, guid, kind); + return ephash_lookup_guid_int (NULL, guid, kind); } void ephash_insert_participant_guid (struct participant *pp) diff --git a/src/core/ddsi/src/q_init.c b/src/core/ddsi/src/q_init.c index 037d794..374ad8e 100644 --- a/src/core/ddsi/src/q_init.c +++ b/src/core/ddsi/src/q_init.c @@ -56,9 +56,11 @@ #include "ddsi/ddsi_raweth.h" #include "ddsi/ddsi_mcgroup.h" #include "ddsi/ddsi_serdata_default.h" +#include "ddsi/ddsi_serdata_builtin.h" -#include "dds__tkmap.h" +#include "ddsi/ddsi_tkmap.h" #include "dds__whc.h" +#include "ddsi/ddsi_iid.h" static void add_peer_addresses (struct addrset *as, const struct config_peer_listelem *list) { @@ -772,7 +774,7 @@ static struct ddsi_sertopic *make_special_topic (uint16_t enc_id, const struct d st->c.ops = &ddsi_sertopic_ops_default; st->c.serdata_ops = ops; st->c.serdata_basehash = ddsi_sertopic_compute_serdata_basehash (st->c.serdata_ops); - st->c.iid = ddsi_plugin.iidgen_fn(); + st->c.iid = ddsi_iid_gen (); st->native_encoding_identifier = enc_id; st->nkeys = 1; return (struct ddsi_sertopic *)st; @@ -782,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) @@ -880,6 +888,7 @@ int rtps_init (void) /* Initialize implementation (Lite or OSPL) */ ddsi_plugin_init (); + ddsi_iid_init (); gv.tstart = now (); /* wall clock time, used in logs */ @@ -1038,7 +1047,7 @@ int rtps_init (void) make_builtin_endpoint_xqos (&gv.builtin_endpoint_xqos_rd, &gv.default_xqos_rd); make_builtin_endpoint_xqos (&gv.builtin_endpoint_xqos_wr, &gv.default_xqos_wr); - make_special_topics (); /* FIXME: leaking these for now */ + make_special_topics (); os_mutexInit (&gv.participant_set_lock); os_condInit (&gv.participant_set_cond, &gv.participant_set_lock); @@ -1060,7 +1069,7 @@ int rtps_init (void) gv.spdp_defrag = nn_defrag_new (NN_DEFRAG_DROP_OLDEST, config.defrag_unreliable_maxsamples); gv.spdp_reorder = nn_reorder_new (NN_REORDER_MODE_ALWAYS_DELIVER, config.primary_reorder_maxsamples); - gv.m_tkmap = dds_tkmap_new (); + gv.m_tkmap = ddsi_tkmap_new (); if (gv.m_factory->m_connless) { @@ -1339,7 +1348,7 @@ err_mc_conn: ddsi_conn_free (gv.data_conn_uc); free_group_membership(gv.mship); err_unicast_sockets: - dds_tkmap_free (gv.m_tkmap); + ddsi_tkmap_free (gv.m_tkmap); nn_reorder_free (gv.spdp_reorder); nn_defrag_free (gv.spdp_defrag); os_mutexDestroy (&gv.spdp_lock); @@ -1368,6 +1377,7 @@ err_unicast_sockets: nn_plist_fini (&gv.default_plist_pp); ddsi_serdatapool_free (gv.serpool); nn_xmsgpool_free (gv.xmsgpool); + ddsi_iid_fini (); (ddsi_plugin.fini_fn) (); #ifdef DDSI_INCLUDE_NETWORK_PARTITIONS err_network_partition_addrset: @@ -1621,7 +1631,7 @@ void rtps_term (void) } } - dds_tkmap_free (gv.m_tkmap); + ddsi_tkmap_free (gv.m_tkmap); ephash_free (gv.guid_hash); gv.guid_hash = NULL; @@ -1663,6 +1673,7 @@ OS_WARNING_MSVC_ON(6001); ddsi_serdatapool_free (gv.serpool); nn_xmsgpool_free (gv.xmsgpool); + ddsi_iid_fini (); (ddsi_plugin.fini_fn) (); DDS_LOG(DDS_LC_CONFIG, "Finis.\n"); } diff --git a/src/core/ddsi/src/q_receive.c b/src/core/ddsi/src/q_receive.c index 3a8e0a7..10f8310 100644 --- a/src/core/ddsi/src/q_receive.c +++ b/src/core/ddsi/src/q_receive.c @@ -46,6 +46,7 @@ #include "ddsi/q_globals.h" #include "ddsi/q_static_assert.h" #include "ddsi/q_init.h" +#include "ddsi/ddsi_tkmap.h" #include "ddsi/ddsi_mcgroup.h" #include "ddsi/ddsi_serdata.h" #include "ddsi/ddsi_serdata_default.h" /* FIXME: get rid of this */ @@ -1995,8 +1996,8 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st the PRISMTECH_WRITER_INFO thing is completely meaningless to us */ { - struct tkmap_instance * tk; - tk = (ddsi_plugin.rhc_plugin.rhc_lookup_fn) (payload); + struct ddsi_tkmap_instance * tk; + tk = ddsi_tkmap_lookup_instance_ref(payload); if (tk) { struct proxy_writer_info pwr_info; @@ -2075,7 +2076,7 @@ retry: if (pwr_locked) os_mutexLock (&pwr->e.lock); } } - (ddsi_plugin.rhc_plugin.rhc_unref_fn) (tk); + ddsi_tkmap_instance_unref (tk); } } ddsi_serdata_unref (payload); diff --git a/src/core/ddsi/src/q_transmit.c b/src/core/ddsi/src/q_transmit.c index 4c0a412..6c314da 100644 --- a/src/core/ddsi/src/q_transmit.c +++ b/src/core/ddsi/src/q_transmit.c @@ -31,7 +31,7 @@ #include "ddsi/q_unused.h" #include "ddsi/q_hbcontrol.h" #include "ddsi/q_static_assert.h" - +#include "ddsi/ddsi_tkmap.h" #include "ddsi/ddsi_serdata.h" #include "ddsi/ddsi_sertopic.h" @@ -851,7 +851,7 @@ int enqueue_sample_wrlock_held (struct writer *wr, seqno_t seq, const struct nn_ return enqueued ? 0 : -1; } -static int insert_sample_in_whc (struct writer *wr, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk) +static int insert_sample_in_whc (struct writer *wr, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk) { /* returns: < 0 on error, 0 if no need to insert in whc, > 0 if inserted */ int do_insert, insres, res; @@ -1027,7 +1027,7 @@ static int maybe_grow_whc (struct writer *wr) return 0; } -static int write_sample_eot (struct nn_xpack *xp, struct writer *wr, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk, int end_of_txn, int gc_allowed) +static int write_sample_eot (struct nn_xpack *xp, struct writer *wr, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk, int end_of_txn, int gc_allowed) { int r; seqno_t seq; @@ -1163,33 +1163,33 @@ drop: return r; } -int write_sample_gc (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata, struct tkmap_instance *tk) +int write_sample_gc (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk) { return write_sample_eot (xp, wr, NULL, serdata, tk, 0, 1); } -int write_sample_nogc (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata, struct tkmap_instance *tk) +int write_sample_nogc (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk) { return write_sample_eot (xp, wr, NULL, serdata, tk, 0, 0); } int write_sample_gc_notk (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata) { - struct tkmap_instance *tk; + struct ddsi_tkmap_instance *tk; int res; - tk = (ddsi_plugin.rhc_plugin.rhc_lookup_fn) (serdata); + tk = ddsi_tkmap_lookup_instance_ref (serdata); res = write_sample_eot (xp, wr, NULL, serdata, tk, 0, 1); - (ddsi_plugin.rhc_plugin.rhc_unref_fn) (tk); + ddsi_tkmap_instance_unref (tk); return res; } int write_sample_nogc_notk (struct nn_xpack *xp, struct writer *wr, struct ddsi_serdata *serdata) { - struct tkmap_instance *tk; + struct ddsi_tkmap_instance *tk; int res; - tk = (ddsi_plugin.rhc_plugin.rhc_lookup_fn) (serdata); + tk = ddsi_tkmap_lookup_instance_ref (serdata); res = write_sample_eot (xp, wr, NULL, serdata, tk, 0, 0); - (ddsi_plugin.rhc_plugin.rhc_unref_fn) (tk); + ddsi_tkmap_instance_unref (tk); return res; } diff --git a/src/core/ddsi/src/q_whc.c b/src/core/ddsi/src/q_whc.c index dd7e95c..3be0df2 100644 --- a/src/core/ddsi/src/q_whc.c +++ b/src/core/ddsi/src/q_whc.c @@ -22,7 +22,7 @@ extern inline void whc_return_sample (struct whc *whc, struct whc_borrowed_sampl extern inline void whc_sample_iter_init (const struct whc *whc, struct whc_sample_iter *it); extern inline bool whc_sample_iter_borrow_next (struct whc_sample_iter *it, struct whc_borrowed_sample *sample); extern inline void whc_free (struct whc *whc); -extern int whc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct tkmap_instance *tk); +extern int whc_insert (struct whc *whc, seqno_t max_drop_seq, seqno_t seq, struct nn_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk); extern unsigned whc_downgrade_to_volatile (struct whc *whc, struct whc_state *st); extern unsigned whc_remove_acked_messages (struct whc *whc, seqno_t max_drop_seq, struct whc_state *whcst, struct whc_node **deferred_free_list); extern void whc_free_deferred_free_list (struct whc *whc, struct whc_node *deferred_free_list); diff --git a/src/core/ddsi/src/q_xevent.c b/src/core/ddsi/src/q_xevent.c index fb545ac..7f9ee9a 100644 --- a/src/core/ddsi/src/q_xevent.c +++ b/src/core/ddsi/src/q_xevent.c @@ -38,6 +38,7 @@ #include "ddsi/q_xmsg.h" #include "ddsi/ddsi_serdata.h" #include "ddsi/ddsi_serdata_default.h" +#include "ddsi/ddsi_tkmap.h" #include "dds__whc.h" #include "ddsi/sysdeps.h" @@ -1128,7 +1129,7 @@ static void write_pmd_message (struct nn_xpack *xp, struct participant *pp, unsi char pad[offsetof (ParticipantMessageData_t, value) + PMD_DATA_LENGTH]; } u; struct ddsi_serdata *serdata; - struct tkmap_instance *tk; + struct ddsi_tkmap_instance *tk; if ((wr = get_builtin_writer (pp, NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER)) == NULL) { @@ -1150,9 +1151,9 @@ static void write_pmd_message (struct nn_xpack *xp, struct participant *pp, unsi serdata = ddsi_serdata_from_sample (gv.rawcdr_topic, SDK_DATA, &raw); serdata->timestamp = now (); - tk = (ddsi_plugin.rhc_plugin.rhc_lookup_fn) (serdata); + tk = ddsi_tkmap_lookup_instance_ref(serdata); write_sample_nogc (xp, wr, serdata, tk); - (ddsi_plugin.rhc_plugin.rhc_unref_fn) (tk); + ddsi_tkmap_instance_unref(tk); #undef PMD_DATA_LENGTH } 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