/* * (c) Copyright, Real-Time Innovations, 2002-2024. * All rights reserved. * * No duplications, whole or partial, manual or electronic, may be made * without express written permission. Any such copies, or * revisions thereof, must display this notice unaltered. * This code contains trade secrets of Real-Time Innovations, Inc. */ #ifndef routingservice_service_h #define routingservice_service_h #include "stdarg.h" #include "routingservice/routingservice_dll.h" #include "ndds/ndds_transport_c.h" #include "routingservice/routingservice_adapter.h" #include "routingservice/routingservice_transformation.h" #include "routingservice/routingservice_processor.h" #include "ndds/ndds_config_c.h" #include "routingservice/ServiceAdmin.h" #include "routingservice/ServiceAdminPlugin.h" #include "routingservice/ServiceAdminSupport.h" #ifdef __cplusplus extern "C" { #endif /*e \file @brief RTI Routing Library API */ /*e \defgroup RTI_RoutingServiceLibModule RTI Routing Library API * * \ingroup ROUTER * * @brief Prototype of the function that gets called upon reception of the * shutdown command. */ typedef void (*RTI_RoutingServiceRemoteShutdownHook_OnShutdownFunction)( void *shutdownHookData); /*e \defgroup RTI_RoutingServiceLibModule RTI Routing Library API * * \ingroup ROUTER * @brief Definition of the interface that handles the remote shutdown. */ struct RTI_RoutingServiceRemoteShutdownHook { /* @brief a place holder for implementors */ void *shutdown_hook_data; /* @brief handles the remote shutdown command */ RTI_RoutingServiceRemoteShutdownHook_OnShutdownFunction on_shutdown; }; #define RTI_RoutingServiceRemoteShutdownHook_INITIALIZER {NULL, NULL} /*e \defgroup RTI_RoutingServiceLibModule RTI Routing Library API * \ingroup ROUTER * @brief Routing Service can be deployed as a C library linked into your application on select architectures. * * This API allows you to create, configure and start RTI Routing Service instances from your application. * * The following code shows the typical use of the API: * * \code * * struct RTI_RoutingServiceProperty property = RTI_RoutingServiceProperty_INITIALIZER; * struct RTI_RoutingService * service = NULL; * * property.cfg_file = "my_routing_service_cfg.xml"; * property.service_name = "my_routing_service"; * ... * * service = RTI_RoutingService_new(&property); * if(service == NULL) { * printf("Error..."); * return -1; * } * * if(!RTI_RoutingService_start(service)) { * printf("Error..."); * RTI_RoutingService_delete(service); * return -1; * } * * while(keep_running) { * sleep(); * ... * } * * RTI_RoutingService_delete(service); * * return 0; * * \endcode * * Instead of a file, you can use XML strings to configure RTI Routing Service. * See \ref RTI_RoutingServiceProperty for more information. *

* To build your application you need to link with the RTI Routing Service library * in <RTI Routing Service home>/bin/<architecture>/ * * If you are using the C API on a Windows, Linux, MAC or INTEGRITY platform: * See the example in * <RTI Routing Service home>/example/wrapperApp * Example makefiles and project files for several architecures are provided. * Also see the README.txt file in the wrapperApp/src directory. * * ### Development Requirements * * | | Linux/macOS Systems | Windows Systems | * | --------------: | :----------------: | :-------------: | * | Shared Libraries| librtirsinfrastructure.so | rtirsinfrastructure.dll | * | ^ | librtidlc.so | rtidlc.dll | * | ^ | librtiapputilsc.so | rtiapputilsc.dll | * | ^ | libnddsmetp.so | nddsmetp.dll | * | ^ | librticonnextmsgc.so | rticonnextmsgc.dll | * | ^ | libnddsc.so | nddsc.dll | * | ^ | librtixml2.so | rtixml2.dll | * | ^ | libnddscore.so | nddscore.dll | * | Headers | routingservice/routingservice_service.h || * */ /*****************************************************************************/ #ifdef DOXYGEN_DOCUMENTATION_ONLY /*e \ingroup RTI_RoutingServiceLibModule * * @brief RTI Routing Service * */ struct RTI_RoutingService {}; #endif struct RTI_RoutingService; /*****************************************************************************/ /*e \ingroup RTI_RoutingServiceLibModule * * @brief Association between a transport alias and its create function pointer * * Allows setting the entry point to load a statically linked transport and * refer to it in the XML configuration through the participant_qos transport configuration. * * If a transport is configured in the XML configuration and its alias * matches the one in this structure, it will be loaded * by \ndds using the specified function pointer. */ struct RTI_RoutingServiceTransportConfig { /*e * @brief An alias defined in the XML configuration to refer to a transport */ char * alias; /*e * @brief Pointer to the function to load the transport */ NDDS_Transport_create_plugin create_function; }; /*e \ingroup RTI_RoutingServiceLibModule * * @brief Configuration of RTI Routing Service * * This structure must be initialized * with \ref RTI_RoutingServiceProperty_INITIALIZER. */ struct RTI_RoutingServiceProperty { /*e * * @brief Path to an RTI Routing Service configuration file * * If not \c NULL, this file is loaded; otherwise, * if \c cfg_strings is not \c NULL, that XML code is loaded. * * \default NULL. */ char * cfg_file; /*e * @brief XML configuration represented as strings * * An array of strings that altogether make up an * XML document to configure RTI Routing Service. This parameter is used * only if \ref cfg_file is \c NULL. * * For example: * * \code * int MY_ROUTING_SERVICE_CFG_SIZE = 3; * const char * MY_ROUTING_SERVICE_CFG[MY_ROUTING_SERVICE_CFG_SIZE] = * {"", * "0..."}; * * property.cfg_strings = MY_ROUTING_SERVICE_CFG; * property.cfg_strings_count = MY_ROUTING_SERVICE_CFG_SIZE; * \endcode * * The reason for using an array instead of one single string is to * get around the limited size of literal strings in C. * In general, if you create the XML string dynamically * using one single string in the array, * setting \ref cfg_strings_count to 1 is enough: * * \code * property.cfg_strings = malloc(sizeof(char *)); * property.cfg_strings[0] = "..."; * property.cfg_strings_count = 1; * \endcode * * If your target system doesn't support a file system, you can use * XML strings to configure the service. To ease this process, a * utility is shipped to generate a C string array from a text file. * You can find this utility in * [RTI Routing Service installation directory]/resource/perl/cStringifyFile.pl * * \default NULL. */ const char ** cfg_strings; /*e * @brief Size of the array \ref cfg_strings * * \default 0. */ int cfg_strings_count; /*e * @brief The name of the Routing Service instance to run * * This is the name used to find the <routing_service> * XML tag in the configuration file; the name that will * be used to refer to this execution in remote administration and * monitoring. * * \default NULL (use RTI_RoutingService) */ char * service_name; /*e * @brief Assigns a name to the execution of the RTI Routing Service. * * Remote commands and status information will refer to the routing * service using this name. * In addition, the name of DomainParticipants created by RTI * Routing Service will be based on this name. * * \default service_name if this value is different than NULL. Otherwise, * "RTI_Routing_Service". */ char * application_name; /*e * * @brief Controls whether the service applies XSD validation to the loaded * configuration. * * \default DDS_BOOLEAN_TRUE */ DDS_Boolean enforce_xsd_validation; /*e * @brief The verbosity of the service * * Values: *

* * \default RTI_ROUTING_SERVICE_LOG_VERBOSITY_EXCEPTIONS */ int service_verbosity; /*e * @brief The verbosity of \ndds core libraries * * Values: * * * \default RTI_ROUTING_SERVICE_LOG_VERBOSITY_EXCEPTIONS */ int dds_verbosity; /*e * @brief Value that is added to the domain IDs of the * domain routes in the XML configuration. * * By using this, an XML file can use relative domain IDs. * * \default 0 */ int domain_id_base; /*e * @brief This path is used to look for plug-in libraries. * * If the plug-in class libraries specified in the XML file don't * contain a full path, RTI Routing Service looks for them in this * directory. If not present, it will rely on the system library path. * * \default NULL (current directory) */ char * plugin_search_path; /*e * @brief Set this to true to if you do not want RTI Routing Service enabled when * \ref RTI_RoutingService_start is called. * * RTI Routing Service can be enabled afterwards through * remote administration. * * \default DDS_BOOLEAN_FALSE */ DDS_Boolean dont_start_service; /*e * @brief Set this to true to enable remote administration * or false to disable it. * * \default DDS_BOOLEAN_FALSE */ DDS_Boolean enable_administration; /*e * @brief If \ref enable_administration is true, this is * the domain ID to use for remote administration. * * Takes precedence over the XML configuration. * If \ref enable_administration is false, this value is not used * even if remote administration is enabled in the XML configuration. * * \default 0 */ int administration_domain_id; /*e * @brief Set it to true to enable remote monitoring * or false to disable it. * * \default DDS_BOOLEAN_FALSE */ DDS_Boolean enable_monitoring; /*e * @brief If \ref enable_monitoring is true, this is * the domain ID to use for remote monitoring. * * Takes precedence over the XML configuration. * If \ref enable_monitoring is false, this value is not used, * even if remote monitoring is enabled in the XML configuration. * * \default 0 */ int monitoring_domain_id; /*e * @brief Clock value that is set as Routing Service internal clock. * The clock must be defined as a comma-delimited list of clocks, * in the order of preference. * Valid clock names are "realtime," "system," and "monotonic." |br| * * By using this, Routing Service can use different clocks. * * \default realtime */ char * internal_clock; /*e * @brief Set it to true to avoid loading the * standard files usually loaded by RTI Routing Service. * * Only the configuration in \ref cfg_file or \ref cfg_strings will be loaded. * * \default DDS_BOOLEAN_FALSE */ DDS_Boolean skip_default_files; /*e * @brief Set this to true to append the host name and process ID * to the RTI Routing Service execution name. * * Used to get unique names for remote administration and monitoring. * * \default DDS_BOOLEAN_FALSE */ DDS_Boolean identify_execution; /*e * @brief Transports to be loaded by \ndds. * * @see \ref registered_transports_count * * @pre Maximum 8 transports */ struct RTI_RoutingServiceTransportConfig registered_transports[8]; /*e * @brief Number of transports configured in \ref registered_transports. * * @pre Minimum 0 (no custom transport to load), maximum 8. * * \default 0 */ int registered_transports_count; /*e * * @brief Path to an RTI Routing Service license file * * If not \c NULL, this file is checked for a valid license; otherwise, * default location will be used. This parameter is only used if your * installation requires a license file. * * \default NULL. */ char * license_file_name; /*e * @brief Dictionary of user variables. * The dictionary provides a parallel way to expand XML configuration * variables in the form $(my_var), when they are not defined in the * environment. * * \default empty */ struct RTI_RoutingServiceProperties user_environment; }; /*e \ingroup RTI_RoutingServiceLibModule * @brief The initial values for an \ref RTI_RoutingServiceProperty instance */ #define RTI_RoutingServiceProperty_INITIALIZER {\ NULL, /* cfg_file */ \ NULL, /* cfg_strings */ \ 0, /* cfg_strings_count */ \ NULL, /* service_name */ \ NULL, /* application_name */ \ DDS_BOOLEAN_TRUE, /* enforce_xsd_validation */ \ RTI_LOG_BIT_FATAL_ERROR | RTI_LOG_BIT_EXCEPTION, /* service_verbosity */ \ RTI_LOG_BIT_FATAL_ERROR | RTI_LOG_BIT_EXCEPTION, /* dds_verbosity */ \ 0, /* domain_id_base */ \ NULL, /* plugin_search_path */ \ RTI_FALSE, /* dont_start_service */ \ RTI_FALSE, /* enable_administration */ \ 0, /* administration_domain_id */ \ RTI_FALSE, /* enable_monitoring */ \ 0, /* monitoring_domain_id */ \ NULL, /* internal_clock */ \ RTI_FALSE, /* skip_default_files */ \ RTI_FALSE, /* identify_execution */ \ { /* registered_transports */ \ {NULL,NULL}, \ {NULL,NULL}, \ {NULL,NULL}, \ {NULL,NULL}, \ {NULL,NULL}, \ {NULL,NULL}, \ {NULL,NULL}, \ {NULL,NULL} \ },\ 0, /* registered_transport_count */ \ NULL, /* license_file_name */ \ {NULL, 0, 1} /* user_environment */ \ } extern ROUTERDllVariable const struct RTI_RoutingServiceProperty RTI_ROUTING_SERVICE_PROPERTY_DEFAULT; extern ROUTERDllExport DDS_Boolean RTI_RoutingServiceProperty_initialize( struct RTI_RoutingServiceProperty *self); extern ROUTERDllExport struct RTI_RoutingServiceProperty * RTI_RoutingServiceProperty_copy( struct RTI_RoutingServiceProperty *to, const struct RTI_RoutingServiceProperty *from); extern ROUTERDllExport void RTI_RoutingServiceProperty_finalize( struct RTI_RoutingServiceProperty *self); /*e \ingroup RTI_RoutingServiceLibModule * @brief Verbosity level: exceptions + warnings + info + periodic + content */ extern ROUTERDllVariable const int RTI_ROUTING_SERVICE_LOG_VERBOSITY_DEBUG; /*e \ingroup RTI_RoutingServiceLibModule * @brief Verbosity level: exceptions + warnings + info + periodic */ extern ROUTERDllVariable const int RTI_ROUTING_SERVICE_LOG_VERBOSITY_ALL; /*e \ingroup RTI_RoutingServiceLibModule * @brief Verbosity level: exceptions + warnings + info */ extern ROUTERDllVariable const int RTI_ROUTING_SERVICE_LOG_VERBOSITY_INFO; /*e \ingroup RTI_RoutingServiceLibModule * @brief Verbosity level: exceptions + warnings */ extern ROUTERDllVariable const int RTI_ROUTING_SERVICE_LOG_VERBOSITY_WARNINGS; /*e \ingroup RTI_RoutingServiceLibModule * @brief Verbosity level: exceptions */ extern ROUTERDllVariable const int RTI_ROUTING_SERVICE_LOG_VERBOSITY_EXCEPTIONS; /*e \ingroup RTI_RoutingServiceLibModule * @brief Verbosity level: silent */ extern ROUTERDllVariable const int RTI_ROUTING_SERVICE_LOG_VERBOSITY_SILENT; /*****************************************************************************/ /*e \ingroup RTI_RoutingServiceLibModule * * @brief Create a new RTI Routing Service instance * * @param property The properties to configure RTI Routing Service. * This parameter is copied internally, so the user is responsible * for releasing any memory allocated inside this structure. * * @mtsafety On non-Linux, non-Windows systems (i.e. VxWorks): * UNSAFE for multiple threads to simultaneously make the FIRST * call to RTI_RoutingService_new(). Subsequent calls are thread safe. * On Windows and Linux systems, these calls are thread-safe. */ extern ROUTERDllExport struct RTI_RoutingService * RTI_RoutingService_new( const struct RTI_RoutingServiceProperty * property); /*e \ingroup RTI_RoutingServiceLibModule * * @brief Stop and delete an RTI Routing Service instance. * * @see \ref RTI_RoutingService_stop * * @param self An \ref RTI_RoutingService instance created with * \ref RTI_RoutingService_new * * @mtsafety * This method is not thread-safe. Calling this method from different threads * for the same Routing Service instance may result in undefined behavior. * * */ extern ROUTERDllExport void RTI_RoutingService_delete(struct RTI_RoutingService * self); /*e \ingroup RTI_RoutingServiceLibModule * * @brief Start RTI Routing Service. * * This is a non-blocking operation. RTI Routing Service will create its own set * of threads to perform its tasks. * * @param self An \ref RTI_RoutingService instance created with * \ref RTI_RoutingService_new * */ extern ROUTERDllExport DDS_Boolean RTI_RoutingService_start(struct RTI_RoutingService * self); /*e \ingroup RTI_RoutingServiceLibModule * * @brief Stop RTI Routing Service. * * This function won't return the execution control until the instance is * fully stopped. * * @param self An \ref RTI_RoutingService instance created with * \ref RTI_RoutingService_new * * @mtsafety * This method is not thread-safe. Calling this method from different threads * for the same Routing Service instance may result in undefined behavior. * */ extern ROUTERDllExport DDS_Boolean RTI_RoutingService_stop(struct RTI_RoutingService * self); /*e \ingroup RTI_RoutingServiceLibModule * * @brief Attach an adapter to be used by routing service when it is started. * * By using this function, an adapter can be statically compiled, created * in your application and have routing service load it, * instead of registering a shared library and a create function * in the configuration. The name passed into this function is the name that has * to be used in the configuration to instantiate connections from the plugin. * * Example: * * \code * * service = RTI_RoutingService_new(&property); * myAdapter = MyAdapter_create(); * * RTI_RoutingService_attach_adapter_plugin(service, myAdapter, "MyAdapter"); * * RTI_RoutingService_start(service); * ... * * \endcode * * And our configuration would look like this: * * \code * * * * * * * ... * * * ... * * * * * \endcode * * This function can be called as many times as desired to attach several plugins. * * Note: The RTI Routing Service Adapter SDK is required. * * @pre Routing Service must not be started. * * @param self An \ref RTI_RoutingService instance not started yet (or stopped) * @param adapter The adapter plugin to be attached * @param plugin_name The name used for this plugin in the <connection> * tags in the configuration * */ extern ROUTERDllExport DDS_Boolean RTI_RoutingService_attach_adapter_plugin( struct RTI_RoutingService * self, void * adapter, const char * plugin_name); /*e \ingroup RTI_RoutingServiceLibModule * * @brief Attach a transformation plugin to be used by Routing Service when * it is started. * * @see RTI_RoutingService_attach_adapter_plugin */ extern ROUTERDllExport DDS_Boolean RTI_RoutingService_attach_transformation_plugin( struct RTI_RoutingService *self, struct RTI_RoutingServiceTransformationPlugin *transformation_plugin, const char *plugin_name); /** \ingroup RTI_RoutingServiceLibModule * * @brief Attach a processor to be used by Routing Service when it is started. * * @see RTI_RoutingService_attach_adapter_plugin * */ extern ROUTERDllExport DDS_Boolean RTI_RoutingService_attach_processor_plugin( struct RTI_RoutingService * self, void * processor_plugin, const char * plugin_name); /** \ingroup RTI_RoutingServiceLibModule * * @brief Set the remote shutdown hook in this Routing Service instance. * * The shutdown hook will be notified upon reception of a remote shutdown * command. * * The operation will fail if the RS is already started. */ extern ROUTERDllExport DDS_Boolean RTI_RoutingService_set_remote_shutdown_hook( struct RTI_RoutingService * self, const struct RTI_RoutingServiceRemoteShutdownHook * shutdown_hook); /** \ingroup RTI_RoutingServiceLibModule * * @brief Executes an Administration command on this service. * * This operation directly executes the specified \p request in this * service as if it was directly received from an administration requester. * * The request can represent any of the available administration operations * as documented in the Administration chapter in the user's manual. This * operation gives you an alternative way to control the service using * the same remote administration interface but allowing you to call * the operation directly. * * @param self \b In. The Routing Service instance. * @param reply \b out. Result of the processing of the command request. * @param request \b In. Request to be processed. */ extern ROUTERDllExport void RTI_RoutingService_execute_command( struct RTI_RoutingService * self, struct RTI_Service_Admin_CommandReply ** reply, const struct RTI_Service_Admin_CommandRequest * request); /** \ingroup RTI_RoutingServiceLibModule * * @brief Returns the reply object that is obtained as result of executing * a command. * * This operation allows the service to release the memory associated to the * reply if needed. * * @param self \b In. The Routing Service instance * @param reply \b In. Reply result of the processing of the command request. */ extern ROUTERDllExport void RTI_RoutingService_return_reply( struct RTI_RoutingService * self, struct RTI_Service_Admin_CommandReply * reply); /** \ingroup RTI_RoutingServiceLibModule * * @deprecated * * This operation has been deprecated and will be removed in future releases. * Routing Service does not require external initialization of the global state. */ extern ROUTERDllExport DDS_Boolean RTI_RoutingService_initialize_globals(void); /** \ingroup RTI_RoutingServiceLibModule * * @deprecated * * This operation has been deprecated and will be removed in future releases. * Routing Service does not require external finalization of the global state. */ extern ROUTERDllExport DDS_Boolean RTI_RoutingService_finalize_globals(void); /** \ingroup RTI_RoutingServiceLibModule * * @brief Return the build ID of this library. * * The build ID uniquely identifies a specific build of the Routing Service * library. */ extern ROUTERDllExport const char* RTI_RoutingService_get_build_number_string(void); /** \ingroup RTI_RoutingServiceLibModule * * @brief Query whether this Routing Service is currently started. */ extern ROUTERDllExport DDS_Boolean RTI_RoutingService_is_started( struct RTI_RoutingService * self); /*e \ingroup RTI_RoutingServiceInfrastructureModule * * @brief Logs as message with the specified level * * The message is specified with a format and a format parameter, in a similar * fashion to the standard C printf() operation. * * The generated log will be part of logging stream of the running * RoutingService, if the \p log_level is part of the configured verbosity. * The result log message may include additional information according to the * Connext logging configuration, such as Advlog Context, thread ID, line number, * etc. Additionally, the result log message will contain a newline character * at the end, so the format does not need to contain it. * * @param[in] log_level Log level associated to the message * @param[in] format message format specification * @param[in] ... variable-length argument (stdarg) */ extern ROUTERDllExport void RTI_RoutingServiceLogger_log( NDDS_Config_LogLevel log_level, const char *format, ...); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* routingservice_service_h */