Line data Source code
1 : /*
2 : * Distributed under the OpenDDS License.
3 : * See: http://www.opendds.org/license.html
4 : */
5 :
6 : #include <DCPS/DdsDcps_pch.h> //Only the _pch include should start with DCPS/
7 :
8 : #include "Service_Participant.h"
9 :
10 : #include "Logging.h"
11 : #include "WaitSet.h"
12 : #include "transport/framework/TransportRegistry.h"
13 : #include "debug.h"
14 : #include "BuiltInTopicUtils.h"
15 : #include "DataDurabilityCache.h"
16 : #include "GuidConverter.h"
17 : #include "MonitorFactory.h"
18 : #include "RecorderImpl.h"
19 : #include "ReplayerImpl.h"
20 : #include "LinuxNetworkConfigMonitor.h"
21 : #include "DefaultNetworkConfigMonitor.h"
22 : #include "StaticDiscovery.h"
23 : #include "ThreadStatusManager.h"
24 : #include "Qos_Helper.h"
25 : #include "../Version.h"
26 : #ifdef OPENDDS_SECURITY
27 : # include "security/framework/SecurityRegistry.h"
28 : #endif
29 :
30 : #include <ace/config.h>
31 : #include <ace/Singleton.h>
32 : #include <ace/Arg_Shifter.h>
33 : #include <ace/Reactor.h>
34 : #include <ace/Select_Reactor.h>
35 : #include <ace/Configuration_Import_Export.h>
36 : #include <ace/Service_Config.h>
37 : #include <ace/Argv_Type_Converter.h>
38 : #include <ace/Auto_Ptr.h>
39 : #include <ace/Sched_Params.h>
40 : #include <ace/Malloc_Allocator.h>
41 : #include <ace/OS_NS_unistd.h>
42 : #include <ace/Version.h>
43 : #include <ace/Configuration.h>
44 : #include <ace/OS_NS_sys_utsname.h>
45 :
46 : #include <cstring>
47 : #ifdef OPENDDS_SAFETY_PROFILE
48 : # include <stdio.h> // <cstdio> after FaceCTS bug 623 is fixed
49 : #else
50 : # include <fstream>
51 : #endif
52 :
53 : #if !defined (__ACE_INLINE__)
54 : #include "Service_Participant.inl"
55 : #endif /* __ACE_INLINE__ */
56 :
57 : namespace {
58 :
59 0 : void set_log_file_name(const char* fname)
60 : {
61 : #ifdef OPENDDS_SAFETY_PROFILE
62 : ACE_LOG_MSG->msg_ostream(fopen(fname, "a"), true);
63 : #else
64 0 : std::ofstream* output_stream = new std::ofstream(fname, ios::app);
65 0 : if (output_stream->bad()) {
66 0 : delete output_stream;
67 : } else {
68 0 : ACE_LOG_MSG->msg_ostream(output_stream, true);
69 : }
70 : #endif
71 0 : ACE_LOG_MSG->clr_flags(ACE_Log_Msg::STDERR | ACE_Log_Msg::LOGGER);
72 0 : ACE_LOG_MSG->set_flags(ACE_Log_Msg::OSTREAM);
73 0 : }
74 :
75 :
76 0 : void set_log_verbose(unsigned long verbose_logging)
77 : {
78 : // Code copied from TAO_ORB_Core::init() in
79 : // TAO version 1.6a_p13.
80 :
81 : typedef void (ACE_Log_Msg::*PTMF)(u_long);
82 0 : PTMF flagop = &ACE_Log_Msg::set_flags;
83 : u_long value;
84 :
85 0 : switch (verbose_logging)
86 : {
87 0 : case 0:
88 0 : flagop = &ACE_Log_Msg::clr_flags;
89 0 : value = ACE_Log_Msg::VERBOSE | ACE_Log_Msg::VERBOSE_LITE;
90 0 : break;
91 0 : case 1:
92 0 : value = ACE_Log_Msg::VERBOSE_LITE; break;
93 0 : default:
94 0 : value = ACE_Log_Msg::VERBOSE; break;
95 : }
96 :
97 0 : (ACE_LOG_MSG->*flagop)(value);
98 0 : }
99 :
100 :
101 : }
102 :
103 : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
104 :
105 : namespace OpenDDS {
106 : namespace DCPS {
107 :
108 : int Service_Participant::zero_argc = 0;
109 :
110 : const size_t DEFAULT_NUM_CHUNKS = 20;
111 :
112 : const size_t DEFAULT_CHUNK_MULTIPLIER = 10;
113 :
114 : const int DEFAULT_FEDERATION_RECOVERY_DURATION = 900; // 15 minutes in seconds.
115 : const int DEFAULT_FEDERATION_INITIAL_BACKOFF_SECONDS = 1; // Wait only 1 second.
116 : const int DEFAULT_FEDERATION_BACKOFF_MULTIPLIER = 2; // Exponential backoff.
117 : const int DEFAULT_FEDERATION_LIVELINESS = 60; // 1 minute hearbeat.
118 :
119 : const int BIT_LOOKUP_DURATION_MSEC = 2000;
120 :
121 : static ACE_TString config_fname(ACE_TEXT(""));
122 :
123 : static const ACE_TCHAR DEFAULT_REPO_IOR[] = ACE_TEXT("file://repo.ior");
124 :
125 : #ifndef OPENDDS_NO_PERSISTENCE_PROFILE
126 : static const char DEFAULT_PERSISTENT_DATA_DIR[] = "OpenDDS-durable-data-dir";
127 : #endif
128 :
129 : static const ACE_TCHAR COMMON_SECTION_NAME[] = ACE_TEXT("common");
130 : static const ACE_TCHAR DOMAIN_SECTION_NAME[] = ACE_TEXT("domain");
131 : static const ACE_TCHAR DOMAIN_RANGE_SECTION_NAME[] = ACE_TEXT("DomainRange");
132 : static const ACE_TCHAR REPO_SECTION_NAME[] = ACE_TEXT("repository");
133 : static const ACE_TCHAR RTPS_SECTION_NAME[] = ACE_TEXT("rtps_discovery");
134 :
135 : static bool got_debug_level = false;
136 : static bool got_use_rti_serialization = false;
137 : static bool got_info = false;
138 : static bool got_chunks = false;
139 : static bool got_chunk_association_multiplier = false;
140 : static bool got_liveliness_factor = false;
141 : static bool got_bit_transport_port = false;
142 : static bool got_bit_transport_ip = false;
143 : static bool got_bit_lookup_duration_msec = false;
144 : static bool got_global_transport_config = false;
145 : static bool got_bit_flag = false;
146 :
147 : #if defined(OPENDDS_SECURITY)
148 : static bool got_security_flag = false;
149 : static bool got_security_debug = false;
150 : static bool got_security_fake_encryption = false;
151 : #endif
152 :
153 : static bool got_publisher_content_filter = false;
154 : static bool got_transport_debug_level = false;
155 : static bool got_pending_timeout = false;
156 : #ifndef OPENDDS_NO_PERSISTENCE_PROFILE
157 : static bool got_persistent_data_dir = false;
158 : #endif
159 : static bool got_default_discovery = false;
160 : #ifndef DDS_DEFAULT_DISCOVERY_METHOD
161 : # ifdef OPENDDS_SAFETY_PROFILE
162 : # define DDS_DEFAULT_DISCOVERY_METHOD Discovery::DEFAULT_RTPS
163 : # else
164 : # define DDS_DEFAULT_DISCOVERY_METHOD Discovery::DEFAULT_REPO
165 : # endif
166 : #endif
167 : static bool got_log_fname = false;
168 : static bool got_log_verbose = false;
169 : static bool got_default_address = false;
170 : static bool got_bidir_giop = false;
171 : static bool got_thread_status_interval = false;
172 : static bool got_monitor = false;
173 : static bool got_type_object_encoding = false;
174 : static bool got_log_level = false;
175 :
176 1 : Service_Participant::Service_Participant()
177 : :
178 : #ifndef OPENDDS_SAFETY_PROFILE
179 1 : ORB_argv_(false /*substitute_env_args*/),
180 : #endif
181 1 : time_source_()
182 1 : , reactor_task_(false)
183 1 : , defaultDiscovery_(DDS_DEFAULT_DISCOVERY_METHOD)
184 1 : , n_chunks_(DEFAULT_NUM_CHUNKS)
185 1 : , association_chunk_multiplier_(DEFAULT_CHUNK_MULTIPLIER)
186 1 : , liveliness_factor_(80)
187 1 : , bit_transport_port_(0)
188 1 : , bit_enabled_(
189 : #ifdef DDS_HAS_MINIMUM_BIT
190 : false
191 : #else
192 : true
193 : #endif
194 : )
195 : #ifdef OPENDDS_SECURITY
196 1 : , security_enabled_(false)
197 : #endif
198 1 : , bit_lookup_duration_msec_(BIT_LOOKUP_DURATION_MSEC)
199 1 : , global_transport_config_(ACE_TEXT(""))
200 1 : , monitor_factory_(0)
201 1 : , federation_recovery_duration_(DEFAULT_FEDERATION_RECOVERY_DURATION)
202 1 : , federation_initial_backoff_seconds_(DEFAULT_FEDERATION_INITIAL_BACKOFF_SECONDS)
203 1 : , federation_backoff_multiplier_(DEFAULT_FEDERATION_BACKOFF_MULTIPLIER)
204 1 : , federation_liveliness_(DEFAULT_FEDERATION_LIVELINESS)
205 : #if OPENDDS_POOL_ALLOCATOR
206 : , pool_size_(1024 * 1024 * 16)
207 : , pool_granularity_(8)
208 : #endif
209 1 : , scheduler_(-1)
210 1 : , priority_min_(0)
211 1 : , priority_max_(0)
212 1 : , publisher_content_filter_(true)
213 : #ifndef OPENDDS_NO_PERSISTENCE_PROFILE
214 1 : , persistent_data_dir_(DEFAULT_PERSISTENT_DATA_DIR)
215 : #endif
216 1 : , bidir_giop_(true)
217 1 : , monitor_enabled_(false)
218 1 : , shut_down_(false)
219 1 : , default_configuration_file_(ACE_TEXT(""))
220 1 : , type_object_encoding_(Encoding_Normal)
221 1 : , network_interface_address_topic_(make_rch<InternalTopic<NetworkInterfaceAddress> >())
222 7 : , printer_value_writer_indent_(4)
223 : {
224 1 : initialize();
225 1 : }
226 :
227 2 : Service_Participant::~Service_Participant()
228 : {
229 1 : if (DCPS_debug_level >= 1) {
230 0 : ACE_DEBUG((LM_DEBUG, "(%P|%t) Service_Participant::~Service_Participant\n"));
231 : }
232 :
233 : {
234 1 : ACE_GUARD(ACE_Thread_Mutex, guard, factory_lock_);
235 1 : if (dp_factory_servant_) {
236 0 : const size_t count = dp_factory_servant_->participant_count();
237 0 : if (count > 0 && log_level >= LogLevel::Warning) {
238 0 : ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: Service_Participant::~Service_Participant: "
239 : "There are %B remaining domain participant(s). "
240 : "It is recommended to delete them before shutdown.\n",
241 : count));
242 : }
243 :
244 0 : const DDS::ReturnCode_t cleanup_status = dp_factory_servant_->delete_all_participants();
245 0 : if (cleanup_status) {
246 0 : if (log_level >= LogLevel::Warning) {
247 0 : ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: Service_Participant::~Service_Participant: "
248 : "delete_all_participants returned %C\n",
249 : retcode_to_string(cleanup_status)));
250 : }
251 : }
252 : }
253 1 : }
254 :
255 1 : const DDS::ReturnCode_t shutdown_status = shutdown();
256 1 : if (shutdown_status != DDS::RETCODE_OK && shutdown_status != DDS::RETCODE_ALREADY_DELETED) {
257 0 : if (log_level >= LogLevel::Warning) {
258 0 : ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: Service_Participant::~Service_Participant: "
259 : "shutdown returned %C\n",
260 : retcode_to_string(shutdown_status)));
261 : }
262 : }
263 1 : }
264 :
265 : Service_Participant*
266 3970 : Service_Participant::instance()
267 : {
268 : // Hide the template instantiation to prevent multiple instances
269 : // from being created.
270 :
271 3970 : return ACE_Singleton<Service_Participant, ACE_SYNCH_MUTEX>::instance();
272 : }
273 :
274 : const TimeSource&
275 5 : Service_Participant::time_source() const
276 : {
277 5 : return time_source_;
278 : }
279 :
280 : ACE_Reactor_Timer_Interface*
281 0 : Service_Participant::timer()
282 : {
283 0 : return reactor_task_.get_reactor();
284 : }
285 :
286 : ACE_Reactor*
287 3 : Service_Participant::reactor()
288 : {
289 3 : return reactor_task_.get_reactor();
290 : }
291 :
292 : ACE_thread_t
293 3 : Service_Participant::reactor_owner() const
294 : {
295 3 : return reactor_task_.get_reactor_owner();
296 : }
297 :
298 : ReactorInterceptor_rch
299 5 : Service_Participant::interceptor() const
300 : {
301 5 : return reactor_task_.interceptor();
302 : }
303 :
304 : JobQueue_rch
305 0 : Service_Participant::job_queue() const
306 : {
307 0 : return job_queue_;
308 : }
309 :
310 59 : DDS::ReturnCode_t Service_Participant::shutdown()
311 : {
312 59 : if (DCPS_debug_level >= 1) {
313 0 : ACE_DEBUG((LM_DEBUG, "(%P|%t) Service_Participant::shutdown\n"));
314 : }
315 :
316 59 : if (shut_down_) {
317 50 : return DDS::RETCODE_ALREADY_DELETED;
318 : }
319 :
320 9 : if (monitor_factory_) {
321 9 : monitor_factory_->deinitialize();
322 9 : monitor_factory_ = 0;
323 : }
324 :
325 : {
326 9 : ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, factory_lock_, DDS::RETCODE_OUT_OF_RESOURCES);
327 9 : if (dp_factory_servant_) {
328 9 : const size_t count = dp_factory_servant_->participant_count();
329 9 : if (count > 0) {
330 0 : if (log_level >= LogLevel::Notice) {
331 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: Service_Participant::shutdown: "
332 : "there are %B domain participant(s) that must be deleted before shutdown can occur\n",
333 : count));
334 : }
335 0 : return DDS::RETCODE_PRECONDITION_NOT_MET;
336 : }
337 : }
338 9 : }
339 :
340 9 : if (shutdown_listener_) {
341 0 : shutdown_listener_->notify_shutdown();
342 : }
343 :
344 9 : DDS::ReturnCode_t rc = DDS::RETCODE_OK;
345 : try {
346 9 : TransportRegistry::instance()->release();
347 : {
348 9 : ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, factory_lock_, DDS::RETCODE_OUT_OF_RESOURCES);
349 :
350 9 : shut_down_ = true;
351 :
352 9 : dp_factory_servant_.reset();
353 :
354 9 : domainRepoMap_.clear();
355 :
356 : {
357 9 : ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, network_config_monitor_lock_,
358 : DDS::RETCODE_OUT_OF_RESOURCES);
359 9 : if (network_config_monitor_) {
360 9 : network_config_monitor_->close();
361 9 : network_config_monitor_->disconnect(network_interface_address_topic_);
362 9 : network_config_monitor_.reset();
363 : }
364 9 : }
365 :
366 9 : domain_ranges_.clear();
367 :
368 9 : reactor_task_.stop();
369 :
370 9 : discoveryMap_.clear();
371 :
372 : #ifndef OPENDDS_NO_PERSISTENCE_PROFILE
373 9 : transient_data_cache_.reset();
374 9 : persistent_data_cache_.reset();
375 : #endif
376 :
377 9 : discovery_types_.clear();
378 9 : }
379 9 : TransportRegistry::close();
380 : #ifdef OPENDDS_SECURITY
381 9 : OpenDDS::Security::SecurityRegistry::close();
382 : #endif
383 0 : } catch (const CORBA::Exception& ex) {
384 0 : if (log_level >= LogLevel::Error) {
385 0 : ex._tao_print_exception("ERROR: Service_Participant::shutdown");
386 : }
387 0 : rc = DDS::RETCODE_ERROR;
388 0 : }
389 :
390 9 : return rc;
391 : }
392 :
393 : #ifdef ACE_USES_WCHAR
394 : DDS::DomainParticipantFactory_ptr
395 : Service_Participant::get_domain_participant_factory(int &argc,
396 : char *argv[])
397 : {
398 : ACE_Argv_Type_Converter converter(argc, argv);
399 : return get_domain_participant_factory(converter.get_argc(),
400 : converter.get_TCHAR_argv());
401 : }
402 : #endif
403 :
404 : DDS::DomainParticipantFactory_ptr
405 9 : Service_Participant::get_domain_participant_factory(int &argc,
406 : ACE_TCHAR *argv[])
407 : {
408 9 : if (!dp_factory_servant_) {
409 9 : ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, factory_lock_, 0);
410 :
411 9 : shut_down_ = false;
412 :
413 9 : if (!dp_factory_servant_) {
414 : // This used to be a call to ORB_init(). Since the ORB is now managed
415 : // by InfoRepoDiscovery, just save the -ORB* args for later use.
416 : // The exceptions are -ORBLogFile and -ORBVerboseLogging, which
417 : // are processed by the service participant. This allows log control
418 : // even if an ORB is not being used.
419 : #ifndef OPENDDS_SAFETY_PROFILE
420 9 : ORB_argv_.add(ACE_TEXT("unused_arg_0"));
421 : #endif
422 : /* NOTE ABOUT ADDING NEW OPTIONS HERE ==================================
423 : *
424 : * The argument parsing here is simple. It will match substrings of
425 : * options even if that isn't the whole option. For example; If
426 : * "-DCPSSecurity" is checked before "-DCPSSecurityDebug" and
427 : * "-DCPSSecurityDebug" is passed, it will match "-DCPSSecurity". Check
428 : * to make sure the order is correct.
429 : *
430 : * TODO/TBD: Create or make use of a stricter command line argument
431 : * parsing method/library. Something where we can define the format of
432 : * the argument and it will handle it better. Maybe could be integrated
433 : * into the config parsing, which has most of these options.
434 : */
435 9 : ACE_Arg_Shifter shifter(argc, argv);
436 27 : while (shifter.is_anything_left()) {
437 18 : if (shifter.cur_arg_strncasecmp(ACE_TEXT("-ORBLogFile")) == 0) {
438 0 : shifter.ignore_arg();
439 18 : } else if (shifter.cur_arg_strncasecmp(ACE_TEXT("-ORBVerboseLogging")) == 0) {
440 0 : shifter.ignore_arg();
441 18 : } else if (shifter.cur_arg_strncasecmp(ACE_TEXT("-ORB")) < 0) {
442 18 : shifter.ignore_arg();
443 : } else {
444 : #ifndef OPENDDS_SAFETY_PROFILE
445 0 : ORB_argv_.add(shifter.get_current());
446 : #endif
447 0 : shifter.consume_arg();
448 0 : if (shifter.is_parameter_next()) {
449 : #ifndef OPENDDS_SAFETY_PROFILE
450 0 : ORB_argv_.add(shifter.get_current(), true /*quote_arg*/);
451 : #endif
452 0 : shifter.consume_arg();
453 : }
454 : }
455 : }
456 :
457 9 : if (parse_args(argc, argv) != 0) {
458 0 : return DDS::DomainParticipantFactory::_nil();
459 : }
460 :
461 9 : if (config_fname.is_empty() && !default_configuration_file_.is_empty()) {
462 0 : config_fname = default_configuration_file_;
463 : }
464 :
465 9 : if (config_fname.is_empty()) {
466 9 : if (DCPS_debug_level) {
467 0 : ACE_DEBUG((LM_NOTICE,
468 : ACE_TEXT("(%P|%t) NOTICE: not using file configuration - no configuration ")
469 : ACE_TEXT("file specified.\n")));
470 : }
471 :
472 : } else {
473 : // Load configuration only if the configuration
474 : // file exists.
475 0 : FILE* in = ACE_OS::fopen(config_fname.c_str(),
476 : ACE_TEXT("r"));
477 :
478 0 : if (!in) {
479 0 : ACE_DEBUG((LM_WARNING,
480 : ACE_TEXT("(%P|%t) WARNING: not using file configuration - ")
481 : ACE_TEXT("can not open \"%s\" for reading. %p\n"),
482 : config_fname.c_str(), ACE_TEXT("fopen")));
483 :
484 : } else {
485 0 : ACE_OS::fclose(in);
486 :
487 0 : if (DCPS_debug_level > 1) {
488 0 : ACE_DEBUG((LM_NOTICE,
489 : ACE_TEXT("(%P|%t) NOTICE: Service_Participant::get_domain_participant_factory ")
490 : ACE_TEXT("Going to load configuration from <%s>\n"),
491 : config_fname.c_str()));
492 : }
493 :
494 0 : if (this->load_configuration() != 0) {
495 0 : ACE_ERROR((LM_ERROR,
496 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::get_domain_participant_factory: ")
497 : ACE_TEXT("load_configuration() failed.\n")));
498 0 : return DDS::DomainParticipantFactory::_nil();
499 : }
500 : }
501 : }
502 : #if OPENDDS_POOL_ALLOCATOR
503 : // For non-FACE tests, configure pool
504 : configure_pool();
505 : #endif
506 :
507 9 : if (log_level >= LogLevel::Info) {
508 0 : ACE_DEBUG((LM_INFO, "(%P|%t) Service_Participant::get_domain_participant_factory: "
509 : "This is OpenDDS " OPENDDS_VERSION " using ACE " ACE_VERSION "\n"));
510 :
511 0 : ACE_DEBUG((LM_INFO, "(%P|%t) Service_Participant::get_domain_participant_factory: "
512 : "log_level: %C DCPS_debug_level: %u\n", log_level.get_as_string(), DCPS_debug_level));
513 :
514 : ACE_utsname uname;
515 0 : if (ACE_OS::uname(&uname) != -1) {
516 0 : ACE_DEBUG((LM_INFO, "(%P|%t) Service_Participant::get_domain_participant_factory: "
517 : "machine: %C, %C platform: %C, %C, %C\n",
518 : uname.nodename, uname.machine, uname.sysname, uname.release, uname.version));
519 : }
520 :
521 0 : ACE_DEBUG((LM_INFO, "(%P|%t) Service_Participant::get_domain_participant_factory: "
522 : "compiler: %C version %d.%d.%d\n",
523 : ACE::compiler_name(), ACE::compiler_major_version(), ACE::compiler_minor_version(), ACE::compiler_beta_version()));
524 : }
525 :
526 : // Establish the default scheduling mechanism and
527 : // priority here. Sadly, the ORB is already
528 : // initialized so we have no influence over its
529 : // scheduling or thread priority(ies).
530 :
531 : /// @TODO: Move ORB initialization to after the
532 : /// configuration file is processed and the
533 : /// initial scheduling policy and priority are
534 : /// established.
535 9 : this->initializeScheduling();
536 :
537 9 : dp_factory_servant_ = make_rch<DomainParticipantFactoryImpl>();
538 :
539 9 : reactor_task_.open_reactor_task(0,
540 : &thread_status_manager_,
541 : "Service_Participant");
542 :
543 9 : job_queue_ = make_rch<JobQueue>(reactor_task_.get_reactor());
544 :
545 9 : if (this->monitor_enabled_) {
546 : #if !defined(ACE_AS_STATIC_LIBS)
547 : ACE_TString directive = ACE_TEXT("dynamic OpenDDS_Monitor Service_Object * OpenDDS_monitor:_make_MonitorFactoryImpl()");
548 : ACE_Service_Config::process_directive(directive.c_str());
549 : #endif
550 0 : this->monitor_factory_ =
551 0 : ACE_Dynamic_Service<MonitorFactory>::instance ("OpenDDS_Monitor");
552 :
553 0 : if (this->monitor_factory_ == 0) {
554 0 : if (this->monitor_enabled_) {
555 0 : ACE_ERROR((LM_ERROR,
556 : ACE_TEXT("ERROR: Service_Participant::get_domain_participant_factory, ")
557 : ACE_TEXT("Unable to enable monitor factory.\n")));
558 : }
559 : }
560 : }
561 :
562 9 : if (this->monitor_factory_ == 0) {
563 : // Use the stubbed factory
564 9 : MonitorFactory::service_initialize();
565 9 : this->monitor_factory_ =
566 9 : ACE_Dynamic_Service<MonitorFactory>::instance ("OpenDDS_Monitor_Default");
567 : }
568 9 : if (this->monitor_enabled_) {
569 0 : this->monitor_factory_->initialize();
570 : }
571 :
572 9 : this->monitor_.reset(this->monitor_factory_->create_sp_monitor(this));
573 9 : }
574 :
575 : #if defined OPENDDS_LINUX_NETWORK_CONFIG_MONITOR
576 9 : if (DCPS_debug_level >= 1) {
577 0 : ACE_DEBUG((LM_DEBUG,
578 : "(%P|%t) Service_Participant::get_domain_participant_factory: Creating LinuxNetworkConfigMonitor\n"));
579 : }
580 9 : network_config_monitor_ = make_rch<LinuxNetworkConfigMonitor>(reactor_task_.interceptor());
581 : #elif defined(OPENDDS_NETWORK_CONFIG_MODIFIER)
582 : if (DCPS_debug_level >= 1) {
583 : ACE_DEBUG((LM_DEBUG,
584 : "(%P|%t) Service_Participant::get_domain_participant_factory: Creating NetworkConfigModifier\n"));
585 : }
586 : network_config_monitor_ = make_rch<NetworkConfigModifier>();
587 : #else
588 : if (DCPS_debug_level >= 1) {
589 : ACE_DEBUG((LM_DEBUG,
590 : "(%P|%t) Service_Participant::get_domain_participant_factory: Creating DefaultNetworkConfigMonitor\n"));
591 : }
592 : network_config_monitor_ = make_rch<DefaultNetworkConfigMonitor>();
593 : #endif
594 :
595 9 : network_config_monitor_->connect(network_interface_address_topic_);
596 9 : if (!network_config_monitor_->open()) {
597 0 : bool open_failed = false;
598 : #ifdef OPENDDS_NETWORK_CONFIG_MODIFIER
599 : if (DCPS_debug_level >= 1) {
600 : ACE_DEBUG((LM_DEBUG,
601 : "(%P|%t) Service_Participant::get_domain_participant_factory: Creating NetworkConfigModifier\n"));
602 : }
603 : network_config_monitor_->disconnect(network_interface_address_topic_);
604 : network_config_monitor_ = make_rch<NetworkConfigModifier>();
605 : network_config_monitor_->connect(network_interface_address_topic_);
606 : if (!network_config_monitor_->open()) {
607 : open_failed = true;
608 : }
609 : #else
610 0 : open_failed = true;
611 : #endif
612 0 : if (open_failed) {
613 0 : if (log_level >= LogLevel::Error) {
614 0 : ACE_ERROR((LM_ERROR,
615 : "(%P|%t) ERROR: Service_Participant::get_domain_participant_factory: Could not open network config monitor\n"));
616 : }
617 0 : network_config_monitor_->close();
618 0 : network_config_monitor_->disconnect(network_interface_address_topic_);
619 0 : network_config_monitor_.reset();
620 : }
621 : }
622 9 : }
623 :
624 9 : return DDS::DomainParticipantFactory::_duplicate(dp_factory_servant_.in());
625 : }
626 :
627 9 : int Service_Participant::parse_args(int& argc, ACE_TCHAR* argv[])
628 : {
629 : // Process logging options first, so they are in effect if we need to log
630 : // while processing other options.
631 9 : ACE_Arg_Shifter log_arg_shifter(argc, argv);
632 27 : while (log_arg_shifter.is_anything_left()) {
633 18 : const ACE_TCHAR* currentArg = 0;
634 :
635 18 : if ((currentArg = log_arg_shifter.get_the_parameter(ACE_TEXT("-ORBLogFile"))) != 0) {
636 0 : set_log_file_name(ACE_TEXT_ALWAYS_CHAR(currentArg));
637 0 : log_arg_shifter.consume_arg();
638 0 : got_log_fname = true;
639 :
640 18 : } else if ((currentArg = log_arg_shifter.get_the_parameter(ACE_TEXT("-ORBVerboseLogging"))) != 0) {
641 0 : set_log_verbose(ACE_OS::atoi(currentArg));
642 0 : log_arg_shifter.consume_arg();
643 0 : got_log_verbose = true;
644 :
645 : } else {
646 18 : log_arg_shifter.ignore_arg();
647 : }
648 : }
649 :
650 9 : ACE_Arg_Shifter arg_shifter(argc, argv);
651 27 : while (arg_shifter.is_anything_left()) {
652 18 : const ACE_TCHAR* currentArg = 0;
653 :
654 18 : if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSDebugLevel"))) != 0) {
655 0 : set_DCPS_debug_level(ACE_OS::atoi(currentArg));
656 0 : arg_shifter.consume_arg();
657 0 : got_debug_level = true;
658 :
659 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSInfoRepo"))) != 0) {
660 0 : this->set_repo_ior(currentArg, Discovery::DEFAULT_REPO);
661 0 : arg_shifter.consume_arg();
662 0 : got_info = true;
663 :
664 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSRTISerialization"))) != 0) {
665 0 : if (ACE_OS::atoi(currentArg) == 0) {
666 0 : ACE_ERROR((LM_WARNING,
667 : ACE_TEXT("(%P|%t) WARNING: Service_Participant::parse_args ")
668 : ACE_TEXT("Argument ignored: DCPSRTISerialization is required to be enabled\n")));
669 : }
670 0 : arg_shifter.consume_arg();
671 0 : got_use_rti_serialization = true;
672 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSChunks"))) != 0) {
673 0 : n_chunks_ = ACE_OS::atoi(currentArg);
674 0 : arg_shifter.consume_arg();
675 0 : got_chunks = true;
676 :
677 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSChunkAssociationMultiplier"))) != 0) {
678 0 : association_chunk_multiplier_ = ACE_OS::atoi(currentArg);
679 0 : arg_shifter.consume_arg();
680 0 : got_chunk_association_multiplier = true;
681 :
682 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSConfigFile"))) != 0) {
683 0 : config_fname = currentArg;
684 0 : arg_shifter.consume_arg();
685 :
686 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSLivelinessFactor"))) != 0) {
687 0 : liveliness_factor_ = ACE_OS::atoi(currentArg);
688 0 : arg_shifter.consume_arg();
689 0 : got_liveliness_factor = true;
690 :
691 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSBitTransportPort"))) != 0) {
692 : /// No need to guard this insertion as we are still single
693 : /// threaded here.
694 0 : this->bit_transport_port_ = ACE_OS::atoi(currentArg);
695 0 : arg_shifter.consume_arg();
696 0 : got_bit_transport_port = true;
697 :
698 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSBitTransportIPAddress"))) != 0) {
699 : /// No need to guard this insertion as we are still single
700 : /// threaded here.
701 0 : this->bit_transport_ip_ = currentArg;
702 0 : arg_shifter.consume_arg();
703 0 : got_bit_transport_ip = true;
704 :
705 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSBitLookupDurationMsec"))) != 0) {
706 0 : bit_lookup_duration_msec_ = ACE_OS::atoi(currentArg);
707 0 : arg_shifter.consume_arg();
708 0 : got_bit_lookup_duration_msec = true;
709 :
710 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSGlobalTransportConfig"))) != 0) {
711 0 : global_transport_config_ = currentArg;
712 0 : arg_shifter.consume_arg();
713 0 : got_global_transport_config = true;
714 :
715 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSBit"))) != 0) {
716 0 : bit_enabled_ = ACE_OS::atoi(currentArg);
717 0 : arg_shifter.consume_arg();
718 0 : got_bit_flag = true;
719 :
720 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSTransportDebugLevel"))) != 0) {
721 0 : OpenDDS::DCPS::Transport_debug_level = ACE_OS::atoi(currentArg);
722 0 : arg_shifter.consume_arg();
723 0 : got_transport_debug_level = true;
724 :
725 : #ifndef OPENDDS_NO_PERSISTENCE_PROFILE
726 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSPersistentDataDir"))) != 0) {
727 0 : this->persistent_data_dir_ = ACE_TEXT_ALWAYS_CHAR(currentArg);
728 0 : arg_shifter.consume_arg();
729 0 : got_persistent_data_dir = true;
730 : #endif
731 :
732 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSPendingTimeout"))) != 0) {
733 0 : pending_timeout_ = TimeDuration(ACE_OS::atoi(currentArg));
734 0 : arg_shifter.consume_arg();
735 0 : got_pending_timeout = true;
736 :
737 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSPublisherContentFilter"))) != 0) {
738 0 : this->publisher_content_filter_ = ACE_OS::atoi(currentArg);
739 0 : arg_shifter.consume_arg();
740 0 : got_publisher_content_filter = true;
741 :
742 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSDefaultDiscovery"))) != 0) {
743 0 : this->defaultDiscovery_ = ACE_TEXT_ALWAYS_CHAR(currentArg);
744 0 : arg_shifter.consume_arg();
745 0 : got_default_discovery = true;
746 :
747 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSBidirGIOP"))) != 0) {
748 0 : bidir_giop_ = ACE_OS::atoi(currentArg);
749 0 : arg_shifter.consume_arg();
750 0 : got_bidir_giop = true;
751 :
752 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSThreadStatusInterval"))) != 0) {
753 0 : thread_status_manager_.thread_status_interval(TimeDuration(ACE_OS::atoi(currentArg)));
754 0 : arg_shifter.consume_arg();
755 0 : got_thread_status_interval = true;
756 :
757 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-FederationRecoveryDuration"))) != 0) {
758 0 : this->federation_recovery_duration_ = ACE_OS::atoi(currentArg);
759 0 : arg_shifter.consume_arg();
760 :
761 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-FederationInitialBackoffSeconds"))) != 0) {
762 0 : this->federation_initial_backoff_seconds_ = ACE_OS::atoi(currentArg);
763 0 : arg_shifter.consume_arg();
764 :
765 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-FederationBackoffMultiplier"))) != 0) {
766 0 : this->federation_backoff_multiplier_ = ACE_OS::atoi(currentArg);
767 0 : arg_shifter.consume_arg();
768 :
769 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-FederationLivelinessDuration"))) != 0) {
770 0 : this->federation_liveliness_ = ACE_OS::atoi(currentArg);
771 0 : arg_shifter.consume_arg();
772 :
773 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSDefaultAddress"))) != 0) {
774 0 : ACE_INET_Addr addr;
775 0 : if (addr.set(u_short(0), currentArg)) {
776 0 : ACE_ERROR_RETURN((LM_ERROR,
777 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::parse_args: ")
778 : ACE_TEXT("failed to parse default address %C\n"),
779 : currentArg),
780 : -1);
781 : }
782 0 : default_address_ = NetworkAddress(addr);
783 0 : arg_shifter.consume_arg();
784 0 : got_default_address = true;
785 :
786 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSMonitor"))) != 0) {
787 0 : this->monitor_enabled_ = ACE_OS::atoi(currentArg);
788 0 : arg_shifter.consume_arg();
789 0 : got_monitor = true;
790 :
791 : #if defined(OPENDDS_SECURITY)
792 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSSecurityDebugLevel"))) != 0) {
793 0 : security_debug.set_debug_level(ACE_OS::atoi(currentArg));
794 0 : arg_shifter.consume_arg();
795 0 : got_security_debug = true;
796 :
797 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSSecurityDebug"))) != 0) {
798 0 : security_debug.parse_flags(currentArg);
799 0 : arg_shifter.consume_arg();
800 0 : got_security_debug = true;
801 :
802 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSSecurityFakeEncryption"))) != 0) {
803 0 : security_debug.fake_encryption = ACE_OS::atoi(currentArg);
804 0 : arg_shifter.consume_arg();
805 0 : got_security_fake_encryption = true;
806 :
807 : // Must be last "-DCPSSecurity*" option, see comment above this arg parsing loop
808 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSSecurity"))) != 0) {
809 0 : security_enabled_ = ACE_OS::atoi(currentArg);
810 0 : arg_shifter.consume_arg();
811 0 : got_security_flag = true;
812 :
813 : #endif
814 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSTypeObjectEncoding"))) != 0) {
815 0 : type_object_encoding(ACE_TEXT_ALWAYS_CHAR(currentArg));
816 0 : arg_shifter.consume_arg();
817 0 : got_type_object_encoding = true;
818 :
819 18 : } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSLogLevel"))) != 0) {
820 0 : log_level.set_from_string(ACE_TEXT_ALWAYS_CHAR(currentArg));
821 0 : arg_shifter.consume_arg();
822 0 : got_log_level = true;
823 :
824 : } else {
825 18 : arg_shifter.ignore_arg();
826 : }
827 : }
828 : // Indicates successful parsing of the command line
829 9 : return 0;
830 9 : }
831 :
832 : void
833 1 : Service_Participant::initialize()
834 : {
835 1 : initial_TransportPriorityQosPolicy_ = TransportPriorityQosPolicyBuilder();
836 1 : initial_LifespanQosPolicy_ = LifespanQosPolicyBuilder();
837 :
838 1 : initial_DurabilityQosPolicy_ = DurabilityQosPolicyBuilder();
839 :
840 1 : initial_DurabilityServiceQosPolicy_ = DurabilityServiceQosPolicyBuilder();
841 :
842 1 : initial_PresentationQosPolicy_.access_scope = DDS::INSTANCE_PRESENTATION_QOS;
843 1 : initial_PresentationQosPolicy_.coherent_access = false;
844 1 : initial_PresentationQosPolicy_.ordered_access = false;
845 :
846 1 : initial_DeadlineQosPolicy_ = DeadlineQosPolicyBuilder();
847 :
848 1 : initial_LatencyBudgetQosPolicy_ = LatencyBudgetQosPolicyBuilder();
849 :
850 1 : initial_OwnershipQosPolicy_ = OwnershipQosPolicyBuilder();
851 1 : initial_OwnershipStrengthQosPolicy_ = OwnershipStrengthQosPolicyBuilder();
852 :
853 1 : initial_LivelinessQosPolicy_ = LivelinessQosPolicyBuilder();
854 :
855 1 : initial_TimeBasedFilterQosPolicy_ = TimeBasedFilterQosPolicyBuilder();
856 :
857 1 : initial_ReliabilityQosPolicy_ = ReliabilityQosPolicyBuilder();
858 :
859 1 : initial_DestinationOrderQosPolicy_ = DestinationOrderQosPolicyBuilder();
860 :
861 1 : initial_HistoryQosPolicy_ = HistoryQosPolicyBuilder();
862 :
863 1 : initial_ResourceLimitsQosPolicy_ = ResourceLimitsQosPolicyBuilder();
864 :
865 1 : initial_EntityFactoryQosPolicy_.autoenable_created_entities = true;
866 :
867 1 : initial_WriterDataLifecycleQosPolicy_ = WriterDataLifecycleQosPolicyBuilder();
868 :
869 : // Will get interpreted based on how the type was annotated.
870 1 : initial_DataRepresentationQosPolicy_.value.length(0);
871 :
872 1 : initial_ReaderDataLifecycleQosPolicy_ = ReaderDataLifecycleQosPolicyBuilder();
873 :
874 1 : initial_TypeConsistencyEnforcementQosPolicy_ = TypeConsistencyEnforcementQosPolicyBuilder();
875 :
876 1 : initial_DomainParticipantQos_.user_data = initial_UserDataQosPolicy_;
877 1 : initial_DomainParticipantQos_.entity_factory = initial_EntityFactoryQosPolicy_;
878 1 : initial_DomainParticipantFactoryQos_.entity_factory = initial_EntityFactoryQosPolicy_;
879 :
880 1 : initial_TopicQos_ = TopicQosBuilder();
881 :
882 1 : initial_DataWriterQos_ = DataWriterQosBuilder();
883 :
884 1 : initial_PublisherQos_.presentation = initial_PresentationQosPolicy_;
885 1 : initial_PublisherQos_.partition = initial_PartitionQosPolicy_;
886 1 : initial_PublisherQos_.group_data = initial_GroupDataQosPolicy_;
887 1 : initial_PublisherQos_.entity_factory = initial_EntityFactoryQosPolicy_;
888 :
889 1 : initial_DataReaderQos_ = DataReaderQosBuilder();
890 :
891 1 : initial_SubscriberQos_.presentation = initial_PresentationQosPolicy_;
892 1 : initial_SubscriberQos_.partition = initial_PartitionQosPolicy_;
893 1 : initial_SubscriberQos_.group_data = initial_GroupDataQosPolicy_;
894 1 : initial_SubscriberQos_.entity_factory = initial_EntityFactoryQosPolicy_;
895 :
896 1 : bit_autopurge_nowriter_samples_delay_.sec = DDS::DURATION_INFINITE_SEC;
897 1 : bit_autopurge_nowriter_samples_delay_.nanosec = DDS::DURATION_INFINITE_NSEC;
898 1 : bit_autopurge_disposed_samples_delay_.sec = DDS::DURATION_INFINITE_SEC;
899 1 : bit_autopurge_disposed_samples_delay_.nanosec = DDS::DURATION_INFINITE_NSEC;
900 1 : }
901 :
902 : void
903 9 : Service_Participant::initializeScheduling()
904 : {
905 : //
906 : // Establish the scheduler if specified.
907 : //
908 9 : if (this->schedulerString_.length() == 0) {
909 9 : if (DCPS_debug_level > 0) {
910 0 : ACE_DEBUG((LM_NOTICE,
911 : ACE_TEXT("(%P|%t) NOTICE: Service_Participant::intializeScheduling() - ")
912 : ACE_TEXT("no scheduling policy specified, not setting policy.\n")));
913 : }
914 :
915 : } else {
916 : //
917 : // Translate the scheduling policy to a usable value.
918 : //
919 0 : int ace_scheduler = ACE_SCHED_OTHER;
920 0 : this->scheduler_ = THR_SCHED_DEFAULT;
921 :
922 0 : if (this->schedulerString_ == ACE_TEXT("SCHED_RR")) {
923 0 : this->scheduler_ = THR_SCHED_RR;
924 0 : ace_scheduler = ACE_SCHED_RR;
925 :
926 0 : } else if (this->schedulerString_ == ACE_TEXT("SCHED_FIFO")) {
927 0 : this->scheduler_ = THR_SCHED_FIFO;
928 0 : ace_scheduler = ACE_SCHED_FIFO;
929 :
930 0 : } else if (this->schedulerString_ == ACE_TEXT("SCHED_OTHER")) {
931 0 : this->scheduler_ = THR_SCHED_DEFAULT;
932 0 : ace_scheduler = ACE_SCHED_OTHER;
933 :
934 : } else {
935 0 : ACE_DEBUG((LM_WARNING,
936 : ACE_TEXT("(%P|%t) WARNING: Service_Participant::initializeScheduling() - ")
937 : ACE_TEXT("unrecognized scheduling policy: %s, set to SCHED_OTHER.\n"),
938 : this->schedulerString_.c_str()));
939 : }
940 :
941 : //
942 : // Attempt to set the scheduling policy.
943 : //
944 : #ifdef ACE_WIN32
945 : ACE_DEBUG((LM_NOTICE,
946 : ACE_TEXT("(%P|%t) NOTICE: Service_Participant::initializeScheduling() - ")
947 : ACE_TEXT("scheduling is not implemented on Win32.\n")));
948 : ACE_UNUSED_ARG(ace_scheduler);
949 : #else
950 : ACE_Sched_Params params(
951 : ace_scheduler,
952 : ACE_Sched_Params::priority_min(ace_scheduler),
953 : ACE_SCOPE_THREAD,
954 0 : schedulerQuantum_.value());
955 :
956 0 : if (ACE_OS::sched_params(params) != 0) {
957 0 : if (ACE_OS::last_error() == EPERM) {
958 0 : ACE_DEBUG((LM_WARNING,
959 : ACE_TEXT("(%P|%t) WARNING: Service_Participant::initializeScheduling() - ")
960 : ACE_TEXT("user is not superuser, requested scheduler not set.\n")));
961 :
962 : } else {
963 0 : ACE_ERROR((LM_ERROR,
964 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::initializeScheduling() - ")
965 : ACE_TEXT("sched_params failed: %m.\n")));
966 : }
967 :
968 : // Reset the scheduler value(s) if we did not succeed.
969 0 : this->scheduler_ = -1;
970 0 : ace_scheduler = ACE_SCHED_OTHER;
971 :
972 0 : } else if (DCPS_debug_level > 0) {
973 0 : ACE_DEBUG((LM_DEBUG,
974 : ACE_TEXT("(%P|%t) Service_Participant::initializeScheduling() - ")
975 : ACE_TEXT("scheduling policy set to %s(%d).\n"),
976 : this->schedulerString_.c_str()));
977 : }
978 :
979 : //
980 : // Setup some scheduler specific information for later use.
981 : //
982 0 : this->priority_min_ = ACE_Sched_Params::priority_min(ace_scheduler, ACE_SCOPE_THREAD);
983 0 : this->priority_max_ = ACE_Sched_Params::priority_max(ace_scheduler, ACE_SCOPE_THREAD);
984 : #endif // ACE_WIN32
985 0 : }
986 9 : }
987 :
988 : #ifdef DDS_HAS_WCHAR
989 : bool
990 0 : Service_Participant::set_repo_ior(const wchar_t* ior,
991 : Discovery::RepoKey key,
992 : bool attach_participant)
993 : {
994 0 : return set_repo_ior(ACE_Wide_To_Ascii(ior).char_rep(), key, attach_participant);
995 : }
996 : #endif
997 :
998 : bool
999 0 : Service_Participant::set_repo_ior(const char* ior,
1000 : Discovery::RepoKey key,
1001 : bool attach_participant)
1002 : {
1003 0 : if (DCPS_debug_level > 0) {
1004 0 : ACE_DEBUG((LM_DEBUG,
1005 : ACE_TEXT("(%P|%t) Service_Participant::set_repo_ior: Repo[%C] == %C\n"),
1006 : key.c_str(), ior));
1007 : }
1008 :
1009 : // This is a global used for the bizarre commandline/configfile
1010 : // processing done for this class.
1011 0 : got_info = true;
1012 :
1013 0 : if (key == "-1") {
1014 0 : key = Discovery::DEFAULT_REPO;
1015 : }
1016 :
1017 0 : const OPENDDS_STRING repo_type = ACE_TEXT_ALWAYS_CHAR(REPO_SECTION_NAME);
1018 0 : if (!discovery_types_.count(repo_type)) {
1019 : // Re-use a transport registry function to attempt a dynamic load of the
1020 : // library that implements the 'repo_type' (InfoRepoDiscovery)
1021 0 : TheTransportRegistry->load_transport_lib(repo_type);
1022 : }
1023 :
1024 0 : if (discovery_types_.count(repo_type)) {
1025 0 : ACE_Configuration_Heap cf;
1026 0 : cf.open();
1027 0 : ACE_Configuration_Section_Key sect_key;
1028 0 : ACE_TString section = REPO_SECTION_NAME;
1029 0 : section += ACE_TEXT('\\');
1030 0 : section += ACE_TEXT_CHAR_TO_TCHAR(key.c_str());
1031 0 : cf.open_section(cf.root_section(), section.c_str(), true /*create*/, sect_key);
1032 0 : cf.set_string_value(sect_key, ACE_TEXT("RepositoryIor"),
1033 : ACE_TEXT_CHAR_TO_TCHAR(ior));
1034 :
1035 0 : discovery_types_[repo_type]->discovery_config(cf);
1036 :
1037 0 : this->remap_domains(key, key, attach_participant);
1038 0 : return true;
1039 0 : }
1040 :
1041 0 : ACE_ERROR_RETURN((LM_ERROR,
1042 : ACE_TEXT("(%P|%t) Service_Participant::set_repo_ior ")
1043 : ACE_TEXT("ERROR - no discovery type registered for ")
1044 : ACE_TEXT("InfoRepoDiscovery\n")),
1045 : false);
1046 0 : }
1047 :
1048 : void
1049 0 : Service_Participant::remap_domains(Discovery::RepoKey oldKey,
1050 : Discovery::RepoKey newKey,
1051 : bool attach_participant)
1052 : {
1053 : // Search the mappings for any domains mapped to this repository.
1054 0 : OPENDDS_VECTOR(DDS::DomainId_t) domainList;
1055 : {
1056 0 : ACE_GUARD(ACE_Recursive_Thread_Mutex, guard, this->maps_lock_);
1057 :
1058 0 : for (DomainRepoMap::const_iterator current = this->domainRepoMap_.begin();
1059 0 : current != this->domainRepoMap_.end();
1060 0 : ++current) {
1061 0 : if (current->second == oldKey) {
1062 0 : domainList.push_back(current->first);
1063 : }
1064 : }
1065 0 : }
1066 :
1067 : // Remap the domains that were attached to this repository.
1068 0 : for (unsigned int index = 0; index < domainList.size(); ++index) {
1069 : // For mapped domains, attach their participants by setting the
1070 : // mapping again.
1071 0 : this->set_repo_domain(domainList[ index], newKey, attach_participant);
1072 : }
1073 0 : }
1074 :
1075 : void
1076 0 : Service_Participant::set_repo_domain(const DDS::DomainId_t domain,
1077 : Discovery::RepoKey key,
1078 : bool attach_participant)
1079 : {
1080 : typedef std::pair<Discovery_rch, GUID_t> DiscRepoPair;
1081 0 : OPENDDS_VECTOR(DiscRepoPair) repoList;
1082 : {
1083 0 : ACE_GUARD(ACE_Recursive_Thread_Mutex, guard, this->maps_lock_);
1084 0 : DomainRepoMap::const_iterator where = this->domainRepoMap_.find(domain);
1085 :
1086 0 : if (key == "-1") {
1087 0 : key = Discovery::DEFAULT_REPO;
1088 : }
1089 :
1090 0 : if ((where == this->domainRepoMap_.end()) || (where->second != key)) {
1091 : // Only assign entries into the map when they change the
1092 : // contents.
1093 0 : this->domainRepoMap_[ domain] = key;
1094 :
1095 0 : if (DCPS_debug_level > 0) {
1096 0 : ACE_DEBUG((LM_DEBUG,
1097 : ACE_TEXT("(%P|%t) Service_Participant::set_repo_domain: ")
1098 : ACE_TEXT("Domain[ %d] = Repo[ %C].\n"),
1099 : domain, key.c_str()));
1100 : }
1101 : }
1102 :
1103 : //
1104 : // Make sure that we mark each DomainParticipant for this domain
1105 : // using this repository as attached to this repository.
1106 : //
1107 : // @TODO: Move this note into user documentation.
1108 : // N.B. Calling set_repo() or set_repo_ior() will result in this
1109 : // code executing again with the new repository. It is best
1110 : // to call those routines first when making changes.
1111 : //
1112 :
1113 : // No servant means no participant. No worries.
1114 0 : if (this->dp_factory_servant_) {
1115 : // Map of domains to sets of participants.
1116 : const DomainParticipantFactoryImpl::DPMap& participants
1117 0 : = this->dp_factory_servant_->participants();
1118 :
1119 : // Extract the set of participants for the current domain.
1120 : DomainParticipantFactoryImpl::DPMap::const_iterator
1121 0 : which = participants.find(domain);
1122 :
1123 0 : if (which != participants.end()) {
1124 : // Extract the repository to attach this domain to.
1125 0 : RepoKeyDiscoveryMap::const_iterator disc_iter = this->discoveryMap_.find(key);
1126 :
1127 0 : if (disc_iter != this->discoveryMap_.end()) {
1128 0 : for (DomainParticipantFactoryImpl::DPSet::const_iterator
1129 0 : current = which->second.begin();
1130 0 : current != which->second.end();
1131 0 : ++current) {
1132 : try {
1133 : // Attach each DomainParticipant in this domain to this
1134 : // repository.
1135 0 : GUID_t id = (*current)->get_id();
1136 0 : repoList.push_back(std::make_pair(disc_iter->second, id));
1137 :
1138 0 : if (DCPS_debug_level > 0) {
1139 0 : ACE_DEBUG((LM_DEBUG,
1140 : ACE_TEXT("(%P|%t) Service_Participant::set_repo_domain: ")
1141 : ACE_TEXT("participant %C attached to Repo[ %C].\n"),
1142 : LogGuid(id).c_str(),
1143 : key.c_str()));
1144 : }
1145 :
1146 0 : } catch (const CORBA::Exception& ex) {
1147 0 : ex._tao_print_exception(
1148 : "ERROR: Service_Participant::set_repo_domain: failed to attach repository - ");
1149 0 : return;
1150 0 : }
1151 : }
1152 : }
1153 : }
1154 0 : }
1155 0 : } // End of GUARD scope.
1156 :
1157 : // Make all of the remote calls after releasing the lock.
1158 0 : for (unsigned int index = 0; index < repoList.size(); ++index) {
1159 0 : if (DCPS_debug_level > 0) {
1160 0 : ACE_DEBUG((LM_DEBUG,
1161 : ACE_TEXT("(%P|%t) Service_Participant::set_repo_domain: ")
1162 : ACE_TEXT("(%d of %d) attaching domain %d participant %C to Repo[ %C].\n"),
1163 : (1+index), repoList.size(), domain,
1164 : LogGuid(repoList[ index].second).c_str(),
1165 : key.c_str()));
1166 : }
1167 :
1168 0 : if (attach_participant)
1169 : {
1170 0 : repoList[ index].first->attach_participant(domain, repoList[ index].second);
1171 : }
1172 : }
1173 0 : }
1174 :
1175 : void
1176 0 : Service_Participant::repository_lost(Discovery::RepoKey key)
1177 : {
1178 : // Find the lost repository.
1179 0 : RepoKeyDiscoveryMap::iterator initialLocation = this->discoveryMap_.find(key);
1180 0 : RepoKeyDiscoveryMap::iterator current = initialLocation;
1181 :
1182 0 : if (current == this->discoveryMap_.end()) {
1183 0 : ACE_DEBUG((LM_WARNING,
1184 : ACE_TEXT("(%P|%t) WARNING: Service_Participant::repository_lost: ")
1185 : ACE_TEXT("lost repository %C was not present, ")
1186 : ACE_TEXT("finding another anyway.\n"),
1187 : key.c_str()));
1188 :
1189 : } else {
1190 : // Start with the repository *after* the lost one.
1191 0 : ++current;
1192 : }
1193 :
1194 : // Calculate the bounding end time for attempts.
1195 0 : const TimeDuration td(federation_recovery_duration());
1196 0 : const MonotonicTimePoint recoveryFailedTime(MonotonicTimePoint::now() + td);
1197 :
1198 : // Backoff delay.
1199 0 : int backoff = this->federation_initial_backoff_seconds();
1200 :
1201 : // Keep trying until the total recovery time specified is exceeded.
1202 0 : while (recoveryFailedTime > MonotonicTimePoint::now()) {
1203 :
1204 : // Wrap to the beginning at the end of the list.
1205 0 : if (current == this->discoveryMap_.end()) {
1206 : // Continue to traverse the list.
1207 0 : current = this->discoveryMap_.begin();
1208 : }
1209 :
1210 : // Handle reaching the lost repository by waiting before trying
1211 : // again.
1212 0 : if (current == initialLocation) {
1213 0 : if (DCPS_debug_level > 0) {
1214 0 : ACE_DEBUG((LM_DEBUG,
1215 : ACE_TEXT("(%P|%t) Service_Participant::repository_lost: ")
1216 : ACE_TEXT("waiting %d seconds to traverse the ")
1217 : ACE_TEXT("repository list another time ")
1218 : ACE_TEXT("for lost key %C.\n"),
1219 : backoff,
1220 : key.c_str()));
1221 : }
1222 :
1223 : // Wait to traverse the list and try again.
1224 0 : ACE_OS::sleep(backoff);
1225 :
1226 : // Exponentially backoff delay.
1227 0 : backoff *= this->federation_backoff_multiplier();
1228 :
1229 : // Don't increment current to allow us to reattach to the
1230 : // original repository if it is restarted.
1231 : }
1232 :
1233 : // Check the availability of the current repository.
1234 0 : if (current->second->active()) {
1235 :
1236 0 : if (DCPS_debug_level > 0) {
1237 0 : ACE_DEBUG((LM_DEBUG,
1238 : ACE_TEXT("(%P|%t) Service_Participant::repository_lost: ")
1239 : ACE_TEXT("replacing repository %C with %C.\n"),
1240 : key.c_str(),
1241 : current->first.c_str()));
1242 : }
1243 :
1244 : // If we reach here, the validate_connection() call succeeded
1245 : // and the repository is reachable.
1246 0 : this->remap_domains(key, current->first);
1247 :
1248 : // Now we are done. This is the only non-failure exit from
1249 : // this method.
1250 0 : return;
1251 :
1252 : } else {
1253 0 : ACE_DEBUG((LM_WARNING,
1254 : ACE_TEXT("(%P|%t) WARNING: Service_Participant::repository_lost: ")
1255 : ACE_TEXT("repository %C was not available to replace %C, ")
1256 : ACE_TEXT("looking for another.\n"),
1257 : current->first.c_str(),
1258 : key.c_str()));
1259 : }
1260 :
1261 : // Move to the next candidate repository.
1262 0 : ++current;
1263 : }
1264 :
1265 : // If we reach here, we have exceeded the total recovery time
1266 : // specified.
1267 0 : OPENDDS_ASSERT(recoveryFailedTime.is_zero());
1268 0 : }
1269 :
1270 : void
1271 0 : Service_Participant::set_default_discovery(const Discovery::RepoKey& key)
1272 : {
1273 0 : this->defaultDiscovery_ = key;
1274 0 : }
1275 :
1276 : Discovery::RepoKey
1277 0 : Service_Participant::get_default_discovery()
1278 : {
1279 0 : return this->defaultDiscovery_;
1280 : }
1281 :
1282 : Discovery_rch
1283 0 : Service_Participant::get_discovery(const DDS::DomainId_t domain)
1284 : {
1285 0 : ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, guard, this->maps_lock_, Discovery_rch());
1286 :
1287 : // Default to the Default InfoRepo-based discovery unless the user has
1288 : // changed defaultDiscovery_ using the API or config file
1289 0 : Discovery::RepoKey repo = defaultDiscovery_;
1290 0 : bool in_range = false;
1291 0 : const Discovery::RepoKey instance_name = get_discovery_template_instance_name(domain);
1292 0 : DomainRange dr_inst;
1293 :
1294 0 : RepoKeyDiscoveryMap::const_iterator location;
1295 :
1296 : // Find if this domain has a repo key (really a discovery key)
1297 : // mapped to it.
1298 0 : DomainRepoMap::const_iterator where = this->domainRepoMap_.find(domain);
1299 0 : if (where != this->domainRepoMap_.end()) {
1300 0 : repo = where->second;
1301 : } else {
1302 : // Is domain part of a DomainRange template?
1303 0 : in_range = get_domain_range_info(domain, dr_inst);
1304 : }
1305 :
1306 : // check to see if this domain has a discovery template
1307 : // and if the template instance has already been loaded.
1308 0 : if (!in_range && is_discovery_template(repo)) {
1309 0 : location = this->discoveryMap_.find(instance_name);
1310 0 : if (location == this->discoveryMap_.end()) {
1311 0 : if (configure_discovery_template(domain, repo)) {
1312 0 : repo = instance_name;
1313 : }
1314 : }
1315 : }
1316 :
1317 0 : location = this->discoveryMap_.find(repo);
1318 :
1319 0 : if (location == this->discoveryMap_.end()) {
1320 0 : if (in_range) {
1321 0 : const int ret = configure_domain_range_instance(domain);
1322 :
1323 : // return the newly configured domain and return it
1324 0 : if (!ret) {
1325 0 : return this->discoveryMap_[instance_name];
1326 : } else {
1327 0 : if (DCPS_debug_level > 0) {
1328 0 : ACE_DEBUG((LM_DEBUG,
1329 : ACE_TEXT("(%P|%t) Service_Participant::get_discovery: ")
1330 : ACE_TEXT("failed attempt to set RTPS discovery for domain range %d.\n"),
1331 : domain));
1332 : }
1333 :
1334 0 : return Discovery_rch();
1335 : }
1336 0 : } else if ((repo == Discovery::DEFAULT_REPO) ||
1337 0 : (repo == "-1")) {
1338 : // Set the default repository IOR if it hasn't already happened
1339 : // by this point. This is why this can't be const.
1340 0 : bool ok = this->set_repo_ior(DEFAULT_REPO_IOR, Discovery::DEFAULT_REPO);
1341 :
1342 0 : if (!ok) {
1343 0 : if (DCPS_debug_level > 0) {
1344 0 : ACE_DEBUG((LM_DEBUG,
1345 : ACE_TEXT("(%P|%t) Service_Participant::get_discovery: ")
1346 : ACE_TEXT("failed attempt to set default IOR for domain %d.\n"),
1347 : domain));
1348 : }
1349 :
1350 : } else {
1351 : // Found the default!
1352 0 : if (DCPS_debug_level > 4) {
1353 0 : ACE_DEBUG((LM_DEBUG,
1354 : ACE_TEXT("(%P|%t) Service_Participant::get_discovery: ")
1355 : ACE_TEXT("returning default repository for domain %d.\n"),
1356 : domain));
1357 : }
1358 :
1359 : }
1360 0 : return this->discoveryMap_[Discovery::DEFAULT_REPO];
1361 :
1362 0 : } else if (repo == Discovery::DEFAULT_RTPS) {
1363 :
1364 0 : ACE_Configuration_Heap cf;
1365 0 : cf.open();
1366 0 : ACE_Configuration_Section_Key k;
1367 0 : cf.open_section(cf.root_section(), RTPS_SECTION_NAME, true /*create*/, k);
1368 :
1369 0 : int status = load_discovery_configuration(cf, RTPS_SECTION_NAME);
1370 :
1371 0 : if (status != 0) {
1372 0 : ACE_ERROR((LM_ERROR,
1373 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::get_Discovery ")
1374 : ACE_TEXT("failed attempt to load default RTPS discovery for domain %d.\n"),
1375 : domain));
1376 :
1377 0 : return Discovery_rch();
1378 : }
1379 :
1380 : // Try to find it again
1381 0 : location = this->discoveryMap_.find(Discovery::DEFAULT_RTPS);
1382 :
1383 0 : if (location == this->discoveryMap_.end()) {
1384 : // Unable to load DEFAULT_RTPS
1385 0 : if (DCPS_debug_level > 0) {
1386 0 : ACE_DEBUG((LM_DEBUG,
1387 : ACE_TEXT("(%P|%t) Service_Participant::get_discovery: ")
1388 : ACE_TEXT("failed attempt to set default RTPS discovery for domain %d.\n"),
1389 : domain));
1390 : }
1391 :
1392 0 : return Discovery_rch();
1393 :
1394 : } else {
1395 : // Found the default!
1396 0 : if (DCPS_debug_level > 4) {
1397 0 : ACE_DEBUG((LM_DEBUG,
1398 : ACE_TEXT("(%P|%t) Service_Participant::get_discovery: ")
1399 : ACE_TEXT("returning default RTPS discovery for domain %d.\n"),
1400 : domain));
1401 : }
1402 :
1403 0 : return location->second;
1404 : }
1405 :
1406 0 : } else {
1407 : // Non-default repositories _must_ be loaded by application.
1408 0 : if (DCPS_debug_level > 4) {
1409 0 : ACE_DEBUG((LM_DEBUG,
1410 : ACE_TEXT("(%P|%t) Service_Participant::get_discovery: ")
1411 : ACE_TEXT("repository for domain %d was not set.\n"),
1412 : domain));
1413 : }
1414 :
1415 0 : return Discovery_rch();
1416 : }
1417 : }
1418 :
1419 0 : if (DCPS_debug_level > 4) {
1420 0 : ACE_DEBUG((LM_DEBUG,
1421 : ACE_TEXT("(%P|%t) Service_Participant::get_discovery: ")
1422 : ACE_TEXT("returning repository for domain %d, repo %C.\n"),
1423 : domain, repo.c_str()));
1424 : }
1425 :
1426 0 : return location->second;
1427 0 : }
1428 :
1429 : OPENDDS_STRING
1430 0 : Service_Participant::bit_transport_ip() const
1431 : {
1432 0 : return ACE_TEXT_ALWAYS_CHAR(this->bit_transport_ip_.c_str());
1433 : }
1434 :
1435 : int
1436 0 : Service_Participant::bit_transport_port() const
1437 : {
1438 0 : return this->bit_transport_port_;
1439 : }
1440 :
1441 : void
1442 0 : Service_Participant::bit_transport_port(int port)
1443 : {
1444 0 : ACE_GUARD(ACE_Recursive_Thread_Mutex, guard, this->maps_lock_);
1445 0 : this->bit_transport_port_ = port;
1446 0 : got_bit_transport_port = true;
1447 0 : }
1448 :
1449 : int
1450 0 : Service_Participant::bit_lookup_duration_msec() const
1451 : {
1452 0 : return bit_lookup_duration_msec_;
1453 : }
1454 :
1455 : void
1456 0 : Service_Participant::bit_lookup_duration_msec(int sec)
1457 : {
1458 0 : bit_lookup_duration_msec_ = sec;
1459 0 : got_bit_lookup_duration_msec = true;
1460 0 : }
1461 :
1462 : size_t
1463 0 : Service_Participant::n_chunks() const
1464 : {
1465 0 : return n_chunks_;
1466 : }
1467 :
1468 : void
1469 0 : Service_Participant::n_chunks(size_t chunks)
1470 : {
1471 0 : n_chunks_ = chunks;
1472 0 : got_chunks = true;
1473 0 : }
1474 :
1475 : size_t
1476 0 : Service_Participant::association_chunk_multiplier() const
1477 : {
1478 0 : return association_chunk_multiplier_;
1479 : }
1480 :
1481 : void
1482 0 : Service_Participant::association_chunk_multiplier(size_t multiplier)
1483 : {
1484 0 : association_chunk_multiplier_ = multiplier;
1485 0 : got_chunk_association_multiplier = true;
1486 0 : }
1487 :
1488 : void
1489 0 : Service_Participant::liveliness_factor(int factor)
1490 : {
1491 0 : liveliness_factor_ = factor;
1492 0 : got_liveliness_factor = true;
1493 0 : }
1494 :
1495 : int
1496 0 : Service_Participant::liveliness_factor() const
1497 : {
1498 0 : return liveliness_factor_;
1499 : }
1500 :
1501 : void
1502 0 : Service_Participant::register_discovery_type(const char* section_name,
1503 : Discovery::Config* cfg)
1504 : {
1505 0 : discovery_types_[section_name].reset(cfg);
1506 0 : }
1507 :
1508 : int
1509 0 : Service_Participant::load_configuration()
1510 : {
1511 0 : ACE_Configuration_Heap cf;
1512 0 : int status = 0;
1513 :
1514 0 : if ((status = cf.open()) != 0)
1515 0 : ACE_ERROR_RETURN((LM_ERROR,
1516 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::load_configuration ")
1517 : ACE_TEXT("open() returned %d\n"),
1518 : status),
1519 : -1);
1520 :
1521 0 : ACE_Ini_ImpExp import(cf);
1522 0 : status = import.import_config(config_fname.c_str());
1523 :
1524 0 : if (status != 0) {
1525 0 : ACE_ERROR_RETURN((LM_ERROR,
1526 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::load_configuration ")
1527 : ACE_TEXT("import_config () returned %d\n"),
1528 : status),
1529 : -1);
1530 : } else {
1531 0 : status = this->load_configuration(cf, config_fname.c_str());
1532 : }
1533 :
1534 0 : return status;
1535 0 : }
1536 :
1537 : int
1538 0 : Service_Participant::load_configuration(
1539 : ACE_Configuration_Heap& config,
1540 : const ACE_TCHAR* filename)
1541 : {
1542 : // Domain config is loaded after Discovery (see below). Since the domain
1543 : // could be a domain_range that specifies the DiscoveryTemplate, check
1544 : // for config templates before loading any config information.
1545 0 : ACE_TString section_name;
1546 :
1547 0 : int status = this->load_common_configuration(config, filename);
1548 :
1549 0 : if (status != 0) {
1550 0 : ACE_ERROR_RETURN((LM_ERROR,
1551 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::load_configuration ")
1552 : ACE_TEXT("load_common_configuration () returned %d\n"),
1553 : status),
1554 : -1);
1555 : }
1556 :
1557 : // Register static discovery.
1558 0 : this->add_discovery(static_rchandle_cast<Discovery>(StaticDiscovery::instance()));
1559 :
1560 : // load any discovery configuration templates before rtps discovery
1561 : // this will populate the domain_range_templates_
1562 0 : status = this->load_domain_ranges(config);
1563 :
1564 : // load any rtps_discovery templates
1565 0 : status = this->load_discovery_templates(config);
1566 :
1567 0 : if (status != 0) {
1568 0 : ACE_ERROR_RETURN((LM_ERROR,
1569 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::load_configuration ")
1570 : ACE_TEXT("load_domain_range_configuration() returned %d\n"),
1571 : status),
1572 : -1);
1573 : }
1574 :
1575 0 : status = this->load_discovery_configuration(config, RTPS_SECTION_NAME);
1576 :
1577 0 : if (status != 0) {
1578 0 : ACE_ERROR_RETURN((LM_ERROR,
1579 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::load_configuration ")
1580 : ACE_TEXT("load_discovery_configuration() returned %d\n"),
1581 : status),
1582 : -1);
1583 : }
1584 :
1585 0 : status = this->load_discovery_configuration(config, REPO_SECTION_NAME);
1586 :
1587 0 : if (status != 0) {
1588 0 : ACE_ERROR_RETURN((LM_ERROR,
1589 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::load_configuration ")
1590 : ACE_TEXT("load_discovery_configuration() returned %d\n"),
1591 : status),
1592 : -1);
1593 : }
1594 :
1595 : // load any transport configuration templates before the transport config
1596 0 : status = TransportRegistry::instance()->load_transport_templates(config);
1597 :
1598 0 : if (status != 0) {
1599 0 : ACE_ERROR_RETURN((LM_ERROR,
1600 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::load_configuration ")
1601 : ACE_TEXT("load_transport_templates() returned %d\n"),
1602 : status),
1603 : -1);
1604 : }
1605 :
1606 0 : status = TransportRegistry::instance()->load_transport_configuration(
1607 : ACE_TEXT_ALWAYS_CHAR(filename), config);
1608 0 : if (this->global_transport_config_ != ACE_TEXT("")) {
1609 : TransportConfig_rch config = TransportRegistry::instance()->get_config(
1610 0 : ACE_TEXT_ALWAYS_CHAR(this->global_transport_config_.c_str()));
1611 0 : if (config) {
1612 0 : TransportRegistry::instance()->global_config(config);
1613 0 : } else if (TheTransportRegistry->config_has_transport_template(global_transport_config_)) {
1614 0 : if (DCPS_debug_level > 0) {
1615 : // This is not an error.
1616 0 : ACE_DEBUG((LM_NOTICE,
1617 : ACE_TEXT("(%P|%t) NOTICE: Service_Participant::load_configuration ")
1618 : ACE_TEXT("DCPSGlobalTransportConfig %C is a transport_template\n"),
1619 : this->global_transport_config_.c_str()));
1620 : }
1621 : } else {
1622 0 : ACE_ERROR_RETURN((LM_ERROR,
1623 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::load_configuration ")
1624 : ACE_TEXT("Unable to locate specified global transport config: %C\n"),
1625 : this->global_transport_config_.c_str()),
1626 : -1);
1627 : }
1628 0 : }
1629 :
1630 0 : if (status != 0) {
1631 0 : ACE_ERROR_RETURN((LM_ERROR,
1632 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::load_configuration ")
1633 : ACE_TEXT("load_transport_configuration () returned %d\n"),
1634 : status),
1635 : -1);
1636 : }
1637 :
1638 : // Needs to be loaded after the [rtps_discovery/*] and [repository/*]
1639 : // sections to allow error reporting on bad discovery config names.
1640 : // Also loaded after the transport configuration so that
1641 : // DefaultTransportConfig within [domain/*] can use TransportConfig objects.
1642 0 : status = this->load_domain_configuration(config, filename);
1643 :
1644 0 : if (status != 0) {
1645 0 : ACE_ERROR_RETURN((LM_ERROR,
1646 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::load_configuration ")
1647 : ACE_TEXT("load_domain_configuration () returned %d\n"),
1648 : status),
1649 : -1);
1650 : }
1651 :
1652 0 : if (status != 0) {
1653 0 : ACE_ERROR_RETURN((LM_ERROR,
1654 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::load_configuration ")
1655 : ACE_TEXT("load_domain_configuration () returned %d\n"),
1656 : status),
1657 : -1);
1658 : }
1659 :
1660 : // Needs to be loaded after transport configs and instances and domains.
1661 : try {
1662 0 : status = StaticDiscovery::instance()->load_configuration(config);
1663 :
1664 0 : if (status != 0) {
1665 0 : ACE_ERROR_RETURN((LM_ERROR,
1666 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::load_configuration ")
1667 : ACE_TEXT("load_discovery_configuration() returned %d\n"),
1668 : status),
1669 : -1);
1670 : }
1671 0 : } catch (const CORBA::BAD_PARAM& ex) {
1672 0 : ex._tao_print_exception("Exception caught in Service_Participant::load_configuration: "
1673 : "trying to load_discovery_configuration()");
1674 0 : return -1;
1675 0 : }
1676 :
1677 0 : return 0;
1678 0 : }
1679 :
1680 : int
1681 0 : Service_Participant::load_common_configuration(ACE_Configuration_Heap& cf,
1682 : const ACE_TCHAR* filename)
1683 : {
1684 0 : const ACE_Configuration_Section_Key &root = cf.root_section();
1685 0 : ACE_Configuration_Section_Key sect;
1686 :
1687 0 : if (cf.open_section(root, COMMON_SECTION_NAME, false, sect) != 0) {
1688 0 : if (DCPS_debug_level > 0) {
1689 : // This is not an error if the configuration file does not have
1690 : // a common section. The code default configuration will be used.
1691 0 : ACE_DEBUG((LM_NOTICE,
1692 : ACE_TEXT("(%P|%t) NOTICE: Service_Participant::load_common_configuration ")
1693 : ACE_TEXT("failed to open section %s\n"),
1694 : COMMON_SECTION_NAME));
1695 : }
1696 :
1697 0 : return 0;
1698 :
1699 : } else {
1700 0 : const ACE_TCHAR* message =
1701 : ACE_TEXT("(%P|%t) NOTICE: using %s value from command option (overrides value if it's in config file)\n");
1702 :
1703 0 : if (got_debug_level) {
1704 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSDebugLevel")));
1705 : } else {
1706 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSDebugLevel"), DCPS_debug_level, int)
1707 : }
1708 :
1709 0 : if (got_info) {
1710 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSInfoRepo")));
1711 : } else {
1712 0 : ACE_TString value;
1713 0 : GET_CONFIG_TSTRING_VALUE(cf, sect, ACE_TEXT("DCPSInfoRepo"), value)
1714 0 : if (!value.empty()) {
1715 0 : this->set_repo_ior(value.c_str(), Discovery::DEFAULT_REPO);
1716 : }
1717 0 : }
1718 :
1719 0 : if (got_use_rti_serialization) {
1720 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSRTISerialization")));
1721 : } else {
1722 0 : bool should_use = true;
1723 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSRTISerialization"), should_use, bool)
1724 0 : if (!should_use) {
1725 0 : ACE_ERROR((LM_WARNING,
1726 : ACE_TEXT("(%P|%t) WARNING: Service_Participant::load_common_configuration ")
1727 : ACE_TEXT("Argument ignored: DCPSRTISerialization is required to be enabled\n")));
1728 : }
1729 : }
1730 :
1731 0 : if (got_chunks) {
1732 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSChunks")));
1733 : } else {
1734 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSChunks"), this->n_chunks_, size_t)
1735 : }
1736 :
1737 0 : if (got_chunk_association_multiplier) {
1738 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSChunkAssociationMultiplier")));
1739 : } else {
1740 : // This is legacy support for a misspelling of the config option.
1741 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSChunkAssociationMutltiplier"), this->association_chunk_multiplier_, size_t)
1742 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSChunkAssociationMultiplier"), this->association_chunk_multiplier_, size_t)
1743 : }
1744 :
1745 0 : if (got_bit_transport_port) {
1746 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSBitTransportPort")));
1747 : } else {
1748 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSBitTransportPort"), this->bit_transport_port_, int)
1749 : }
1750 :
1751 0 : if (got_bit_transport_ip) {
1752 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSBitTransportIPAddress")));
1753 : } else {
1754 0 : GET_CONFIG_TSTRING_VALUE(cf, sect, ACE_TEXT("DCPSBitTransportIPAddress"), this->bit_transport_ip_)
1755 : }
1756 :
1757 0 : if (got_liveliness_factor) {
1758 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSLivelinessFactor")));
1759 : } else {
1760 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSLivelinessFactor"), this->liveliness_factor_, int)
1761 : }
1762 :
1763 0 : if (got_bit_lookup_duration_msec) {
1764 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSBitLookupDurationMsec")));
1765 : } else {
1766 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSBitLookupDurationMsec"), this->bit_lookup_duration_msec_, int)
1767 : }
1768 :
1769 0 : if (got_global_transport_config) {
1770 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSGlobalTransportConfig")));
1771 : } else {
1772 0 : GET_CONFIG_TSTRING_VALUE(cf, sect, ACE_TEXT("DCPSGlobalTransportConfig"), this->global_transport_config_);
1773 0 : if (this->global_transport_config_ == ACE_TEXT("$file")) {
1774 : // When the special string of "$file" is used, substitute the file name
1775 0 : this->global_transport_config_ = filename;
1776 : }
1777 : }
1778 :
1779 0 : if (got_bit_flag) {
1780 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSBit")));
1781 : } else {
1782 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSBit"), this->bit_enabled_, int)
1783 : }
1784 :
1785 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSLogBits"), log_bits, bool);
1786 :
1787 : #if defined(OPENDDS_SECURITY)
1788 0 : if (got_security_flag) {
1789 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSSecurity")));
1790 : } else {
1791 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSSecurity"), this->security_enabled_, int)
1792 : }
1793 :
1794 0 : if (got_security_debug) {
1795 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSSecurityDebug or DCPSSecurityDebugLevel")));
1796 : } else {
1797 0 : const ACE_TCHAR* debug_name = ACE_TEXT("DCPSSecurityDebug");
1798 0 : const ACE_TCHAR* debug_level_name = ACE_TEXT("DCPSSecurityDebugLevel");
1799 0 : bool got_value = false;
1800 0 : ACE_TString debug_level_value;
1801 0 : if (cf.get_string_value(sect, debug_level_name, debug_level_value) == -1) {
1802 0 : ACE_TString debug_value;
1803 0 : if (cf.get_string_value(sect, debug_name, debug_value) != -1) {
1804 0 : if (debug_value != ACE_TEXT("")) {
1805 0 : got_value = true;
1806 0 : security_debug.parse_flags(debug_value.c_str());
1807 : }
1808 : }
1809 0 : } else if (debug_level_value != ACE_TEXT("")) {
1810 0 : got_value = true;
1811 0 : security_debug.set_debug_level(ACE_OS::atoi(debug_level_value.c_str()));
1812 : }
1813 0 : if (!got_value && OpenDDS::DCPS::Transport_debug_level > 0) {
1814 0 : ACE_DEBUG((LM_NOTICE,
1815 : ACE_TEXT("(%P|%t) NOTICE: DCPSSecurityDebug and DCPSSecurityDebugLevel ")
1816 : ACE_TEXT("are not defined in config file or are blank - using code default.\n")));
1817 : }
1818 0 : }
1819 :
1820 0 : if (got_security_fake_encryption) {
1821 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSSecurityFakeEncryption")));
1822 : } else {
1823 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSSecurityFakeEncryption"), security_debug.fake_encryption, int)
1824 : }
1825 : #endif
1826 :
1827 0 : if (got_transport_debug_level) {
1828 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSTransportDebugLevel")));
1829 : } else {
1830 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSTransportDebugLevel"), OpenDDS::DCPS::Transport_debug_level, int)
1831 : }
1832 :
1833 : #ifndef OPENDDS_NO_PERSISTENCE_PROFILE
1834 0 : if (got_persistent_data_dir) {
1835 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSPersistentDataDir")));
1836 : } else {
1837 0 : ACE_TString value;
1838 0 : GET_CONFIG_TSTRING_VALUE(cf, sect, ACE_TEXT("DCPSPersistentDataDir"), value)
1839 0 : this->persistent_data_dir_ = ACE_TEXT_ALWAYS_CHAR(value.c_str());
1840 0 : }
1841 : #endif
1842 :
1843 0 : if (got_pending_timeout) {
1844 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSPendingTimeout")));
1845 : } else {
1846 0 : int timeout = 0;
1847 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSPendingTimeout"), timeout, int)
1848 0 : pending_timeout_ = TimeDuration(timeout);
1849 : }
1850 :
1851 0 : if (got_publisher_content_filter) {
1852 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSPublisherContentFilter")));
1853 : } else {
1854 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSPublisherContentFilter"),
1855 : this->publisher_content_filter_, bool)
1856 : }
1857 :
1858 0 : if (got_default_discovery) {
1859 : ACE_Configuration::VALUETYPE type;
1860 0 : if (cf.find_value(sect, ACE_TEXT("DCPSDefaultDiscovery"), type) != -1) {
1861 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSDefaultDiscovery")));
1862 : }
1863 : } else {
1864 0 : GET_CONFIG_STRING_VALUE(cf, sect, ACE_TEXT("DCPSDefaultDiscovery"),
1865 : this->defaultDiscovery_);
1866 : }
1867 :
1868 0 : if (got_bidir_giop) {
1869 : ACE_Configuration::VALUETYPE type;
1870 0 : if (cf.find_value(sect, ACE_TEXT("DCPSBidirGIOP"), type) != -1) {
1871 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSBidirGIOP")));
1872 : }
1873 : } else {
1874 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSBidirGIOP"), bidir_giop_, bool)
1875 : }
1876 :
1877 0 : if (got_thread_status_interval) {
1878 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSThreadStatusInterval")));
1879 : } else {
1880 0 : int interval = 0;
1881 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSThreadStatusInterval"), interval, int);
1882 0 : thread_status_manager_.thread_status_interval(TimeDuration(interval));
1883 : }
1884 :
1885 : ACE_Configuration::VALUETYPE type;
1886 0 : if (got_log_fname) {
1887 0 : if (cf.find_value(sect, ACE_TEXT("ORBLogFile"), type) != -1) {
1888 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("ORBLogFile")));
1889 : }
1890 : } else {
1891 0 : OPENDDS_STRING log_fname;
1892 0 : GET_CONFIG_STRING_VALUE(cf, sect, ACE_TEXT("ORBLogFile"), log_fname);
1893 0 : if (!log_fname.empty()) {
1894 0 : set_log_file_name(log_fname.c_str());
1895 : }
1896 0 : }
1897 :
1898 0 : if (got_log_verbose) {
1899 0 : if (cf.find_value(sect, ACE_TEXT("ORBVerboseLogging"), type) != -1) {
1900 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("ORBVerboseLogging")));
1901 : }
1902 : } else {
1903 0 : unsigned long verbose_logging = 0;
1904 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("ORBVerboseLogging"), verbose_logging, unsigned long);
1905 0 : set_log_verbose(verbose_logging);
1906 : }
1907 :
1908 0 : if (got_default_address) {
1909 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSDefaultAddress")));
1910 : } else {
1911 0 : ACE_TString default_address_str;
1912 0 : GET_CONFIG_TSTRING_VALUE(cf, sect, ACE_TEXT("DCPSDefaultAddress"), default_address_str);
1913 0 : ACE_INET_Addr addr;
1914 0 : if (!default_address_str.empty() &&
1915 0 : addr.set(u_short(0), default_address_str.c_str())) {
1916 0 : ACE_ERROR_RETURN((LM_ERROR,
1917 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::load_common_configuration: ")
1918 : ACE_TEXT("failed to parse default address %C\n"),
1919 : default_address_str.c_str()),
1920 : -1);
1921 : }
1922 0 : default_address_ = NetworkAddress(addr);
1923 0 : }
1924 :
1925 0 : if (got_monitor) {
1926 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSMonitor")));
1927 : } else {
1928 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("DCPSMonitor"), monitor_enabled_, bool)
1929 : }
1930 :
1931 0 : if (got_type_object_encoding) {
1932 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSTypeObjectEncoding")));
1933 : } else {
1934 0 : String str;
1935 0 : GET_CONFIG_STRING_VALUE(cf, sect, ACE_TEXT("DCPSTypeObjectEncoding"), str);
1936 0 : if (!str.empty()) {
1937 0 : type_object_encoding(str.c_str());
1938 : }
1939 0 : }
1940 :
1941 0 : if (got_log_level) {
1942 0 : ACE_DEBUG((LM_NOTICE, message, ACE_TEXT("DCPSLogLevel")));
1943 : } else {
1944 0 : String str;
1945 0 : GET_CONFIG_STRING_VALUE(cf, sect, ACE_TEXT("DCPSLogLevel"), str);
1946 0 : if (!str.empty()) {
1947 0 : log_level.set_from_string(str.c_str());
1948 : }
1949 0 : }
1950 :
1951 : // These are not handled on the command line.
1952 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("FederationRecoveryDuration"), this->federation_recovery_duration_, int)
1953 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("FederationInitialBackoffSeconds"), this->federation_initial_backoff_seconds_, int)
1954 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("FederationBackoffMultiplier"), this->federation_backoff_multiplier_, int)
1955 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("FederationLivelinessDuration"), this->federation_liveliness_, int)
1956 :
1957 : #if OPENDDS_POOL_ALLOCATOR
1958 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("pool_size"), pool_size_, size_t)
1959 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("pool_granularity"), pool_granularity_, size_t)
1960 : #endif
1961 :
1962 : //
1963 : // Establish the scheduler if specified.
1964 : //
1965 0 : GET_CONFIG_TSTRING_VALUE(cf, sect, ACE_TEXT("scheduler"), this->schedulerString_)
1966 :
1967 0 : suseconds_t usec(0);
1968 :
1969 0 : GET_CONFIG_VALUE(cf, sect, ACE_TEXT("scheduler_slice"), usec, suseconds_t)
1970 :
1971 0 : if (usec > 0) {
1972 0 : schedulerQuantum_ = TimeDuration(0, usec);
1973 : }
1974 : }
1975 :
1976 0 : return 0;
1977 0 : }
1978 :
1979 : int
1980 0 : Service_Participant::load_domain_configuration(ACE_Configuration_Heap& cf,
1981 : const ACE_TCHAR* filename)
1982 : {
1983 0 : const ACE_Configuration_Section_Key& root = cf.root_section();
1984 0 : ACE_Configuration_Section_Key domain_sect;
1985 :
1986 0 : if (cf.open_section(root, DOMAIN_SECTION_NAME, false, domain_sect) != 0) {
1987 0 : if (DCPS_debug_level > 0) {
1988 : // This is not an error if the configuration file does not have
1989 : // any domain (sub)section. The code default configuration will be used.
1990 0 : ACE_DEBUG((LM_NOTICE,
1991 : ACE_TEXT("(%P|%t) NOTICE: Service_Participant::load_domain_configuration(): ")
1992 : ACE_TEXT("failed to open [%s] section - using code default.\n"),
1993 : DOMAIN_SECTION_NAME));
1994 : }
1995 :
1996 0 : return 0;
1997 :
1998 : } else {
1999 : // Ensure there are no properties in this section
2000 0 : ValueMap vm;
2001 0 : if (pullValues(cf, domain_sect, vm) > 0) {
2002 : // There are values inside [domain]
2003 0 : ACE_ERROR_RETURN((LM_ERROR,
2004 : ACE_TEXT("(%P|%t) Service_Participant::load_domain_configuration(): ")
2005 : ACE_TEXT("domain sections must have a subsection name\n")),
2006 : -1);
2007 : }
2008 : // Process the subsections of this section (the individual domains)
2009 0 : KeyList keys;
2010 0 : if (processSections(cf, domain_sect, keys) != 0) {
2011 0 : ACE_ERROR_RETURN((LM_ERROR,
2012 : ACE_TEXT("(%P|%t) Service_Participant::load_domain_configuration(): ")
2013 : ACE_TEXT("too many nesting layers in the [domain] section.\n")),
2014 : -1);
2015 : }
2016 :
2017 : // Loop through the [domain/*] sections
2018 0 : for (KeyList::const_iterator it = keys.begin(); it != keys.end(); ++it) {
2019 0 : OPENDDS_STRING domain_name = it->first;
2020 :
2021 0 : ValueMap values;
2022 0 : pullValues(cf, it->second, values);
2023 0 : DDS::DomainId_t domainId = -1;
2024 0 : Discovery::RepoKey repoKey;
2025 0 : OPENDDS_STRING perDomainDefaultTportConfig;
2026 0 : for (ValueMap::const_iterator it = values.begin(); it != values.end(); ++it) {
2027 0 : OPENDDS_STRING name = it->first;
2028 0 : if (name == "DomainId") {
2029 0 : OPENDDS_STRING value = it->second;
2030 0 : if (!convertToInteger(value, domainId)) {
2031 0 : ACE_ERROR_RETURN((LM_ERROR,
2032 : ACE_TEXT("(%P|%t) Service_Participant::load_domain_configuration(): ")
2033 : ACE_TEXT("Illegal integer value for DomainId (%C) in [domain/%C] section.\n"),
2034 : value.c_str(), domain_name.c_str()),
2035 : -1);
2036 : }
2037 0 : if (DCPS_debug_level > 0) {
2038 0 : ACE_DEBUG((LM_DEBUG,
2039 : ACE_TEXT("(%P|%t) [domain/%C]: DomainId == %d\n"),
2040 : domain_name.c_str(), domainId));
2041 : }
2042 0 : } else if (name == "DomainRepoKey") {
2043 : // We will still process this for backward compatibility, but
2044 : // it can now be replaced by "DiscoveryConfig=REPO:<key>"
2045 0 : repoKey = it->second;
2046 0 : if (repoKey == "-1") {
2047 0 : repoKey = Discovery::DEFAULT_REPO;
2048 : }
2049 :
2050 0 : if (DCPS_debug_level > 0) {
2051 0 : ACE_DEBUG((LM_DEBUG,
2052 : ACE_TEXT("(%P|%t) [domain/%C]: DomainRepoKey == %C\n"),
2053 : domain_name.c_str(), repoKey.c_str()));
2054 : }
2055 0 : } else if (name == "DiscoveryConfig") {
2056 0 : repoKey = it->second;
2057 0 : } else if (name == "DefaultTransportConfig") {
2058 0 : if (it->second == "$file") {
2059 : // When the special string of "$file" is used, substitute the file name
2060 0 : perDomainDefaultTportConfig = ACE_TEXT_ALWAYS_CHAR(filename);
2061 :
2062 : } else {
2063 0 : perDomainDefaultTportConfig = it->second;
2064 : }
2065 :
2066 : } else {
2067 0 : ACE_ERROR_RETURN((LM_ERROR,
2068 : ACE_TEXT("(%P|%t) Service_Participant::load_domain_configuration(): ")
2069 : ACE_TEXT("Unexpected entry (%C) in [domain/%C] section.\n"),
2070 : name.c_str(), domain_name.c_str()),
2071 : -1);
2072 : }
2073 0 : }
2074 :
2075 0 : if (domainId == -1) {
2076 : // DomainId parameter is not set, try using the domain name as an ID
2077 0 : if (!convertToInteger(domain_name, domainId)) {
2078 0 : ACE_ERROR_RETURN((LM_ERROR,
2079 : ACE_TEXT("(%P|%t) Service_Participant::load_domain_configuration(): ")
2080 : ACE_TEXT("Missing DomainId value in [domain/%C] section.\n"),
2081 : domain_name.c_str()),
2082 : -1);
2083 : }
2084 : }
2085 :
2086 0 : if (!perDomainDefaultTportConfig.empty()) {
2087 0 : TransportRegistry* const reg = TransportRegistry::instance();
2088 0 : TransportConfig_rch tc = reg->get_config(perDomainDefaultTportConfig);
2089 0 : if (tc.is_nil()) {
2090 0 : ACE_ERROR_RETURN((LM_ERROR,
2091 : ACE_TEXT("(%P|%t) Service_Participant::load_domain_configuration(): ")
2092 : ACE_TEXT("Unknown transport config %C in [domain/%C] section.\n"),
2093 : perDomainDefaultTportConfig.c_str(), domain_name.c_str()), -1);
2094 : } else {
2095 0 : reg->domain_default_config(domainId, tc);
2096 : }
2097 0 : }
2098 :
2099 : // Check to see if the specified discovery configuration has been defined
2100 0 : if (!repoKey.empty()) {
2101 0 : if ((repoKey != Discovery::DEFAULT_REPO) &&
2102 0 : (repoKey != Discovery::DEFAULT_RTPS) &&
2103 0 : (repoKey != Discovery::DEFAULT_STATIC) &&
2104 0 : (this->discoveryMap_.find(repoKey) == this->discoveryMap_.end())) {
2105 0 : ACE_ERROR_RETURN((LM_ERROR,
2106 : ACE_TEXT("(%P|%t) Service_Participant::load_domain_configuration(): ")
2107 : ACE_TEXT("Specified configuration (%C) not found. Referenced in [domain/%C] section.\n"),
2108 : repoKey.c_str(), domain_name.c_str()),
2109 : -1);
2110 : }
2111 0 : this->set_repo_domain(domainId, repoKey);
2112 : }
2113 0 : }
2114 0 : }
2115 :
2116 0 : return 0;
2117 0 : }
2118 :
2119 : int
2120 0 : Service_Participant::load_domain_ranges(ACE_Configuration_Heap& cf)
2121 : {
2122 0 : const ACE_Configuration_Section_Key& root = cf.root_section();
2123 0 : ACE_Configuration_Section_Key domain_range_sect;
2124 :
2125 0 : if (cf.open_section(root, DOMAIN_RANGE_SECTION_NAME, false, domain_range_sect) != 0) {
2126 0 : if (DCPS_debug_level > 0) {
2127 : // This is not an error if the configuration file does not have
2128 : // any domain range (sub)section.
2129 0 : ACE_DEBUG((LM_NOTICE,
2130 : ACE_TEXT("(%P|%t) NOTICE: Service_Participant::load_domain_ranges(): ")
2131 : ACE_TEXT("config does not have a [%s] section.\n"),
2132 : DOMAIN_RANGE_SECTION_NAME));
2133 : }
2134 :
2135 0 : return 0;
2136 :
2137 : } else {
2138 0 : if (DCPS_debug_level > 0) {
2139 0 : ACE_DEBUG((LM_NOTICE,
2140 : ACE_TEXT("(%P|%t) NOTICE: Service_Participant::load_domain_ranges(): ")
2141 : ACE_TEXT("config has %s sections.\n"),
2142 : DOMAIN_RANGE_SECTION_NAME));
2143 : }
2144 :
2145 : // Ensure there are no properties in this section
2146 0 : ValueMap vm;
2147 0 : if (pullValues(cf, domain_range_sect, vm) > 0) {
2148 : // There are values inside [DomainRange]
2149 0 : ACE_ERROR_RETURN((LM_ERROR,
2150 : ACE_TEXT("(%P|%t) Service_Participant::load_domain_ranges(): ")
2151 : ACE_TEXT("[%s] sections must have a subsection range\n"),
2152 : DOMAIN_RANGE_SECTION_NAME),
2153 : -1);
2154 : }
2155 :
2156 : // Process the subsections of this section (the ranges, m-n)
2157 0 : KeyList keys;
2158 0 : if (processSections(cf, domain_range_sect, keys) != 0) {
2159 0 : ACE_ERROR_RETURN((LM_ERROR,
2160 : ACE_TEXT("(%P|%t) Service_Participant::load_domain_ranges(): ")
2161 : ACE_TEXT("too many nesting layers in the [%s] section.\n"),
2162 : DOMAIN_RANGE_SECTION_NAME),
2163 : -1);
2164 : }
2165 :
2166 : // Loop through the [DomainRange/*] sections
2167 0 : for (KeyList::const_iterator it = keys.begin(); it != keys.end(); ++it) {
2168 0 : OPENDDS_STRING domain_range = it->first;
2169 :
2170 0 : DomainRange range_element;
2171 :
2172 0 : int range_start = -1;
2173 0 : int range_end = -1;
2174 :
2175 0 : if (parse_domain_range(domain_range, range_start, range_end) != 0) {
2176 0 : ACE_ERROR_RETURN((LM_ERROR,
2177 : ACE_TEXT("(%P|%t) Service_Participant::load_domain_ranges(): ")
2178 : ACE_TEXT("Error parsing [%s/%C] section.\n"),
2179 : DOMAIN_RANGE_SECTION_NAME,
2180 : domain_range.c_str()),
2181 : -1);
2182 : }
2183 :
2184 0 : range_element.range_start = range_start;
2185 0 : range_element.range_end = range_end;
2186 :
2187 0 : ValueMap values;
2188 0 : if (pullValues(cf, it->second, values) > 0) {
2189 0 : OPENDDS_STRING dt_name;
2190 :
2191 0 : for (ValueMap::const_iterator it = values.begin(); it != values.end(); ++it) {
2192 0 : OPENDDS_STRING name = it->first;
2193 0 : if (name == "DiscoveryTemplate") {
2194 0 : dt_name = it->second;
2195 0 : if (DCPS_debug_level > 0) {
2196 0 : ACE_DEBUG((LM_DEBUG,
2197 : ACE_TEXT("(%P|%t) [%s/%C]: DiscoveryTemplate name == %C\n"),
2198 : DOMAIN_RANGE_SECTION_NAME, domain_range.c_str(), dt_name.c_str()));
2199 : }
2200 0 : range_element.discovery_template_name = dt_name;
2201 0 : } else if (name == "DefaultTransportConfig") {
2202 0 : range_element.transport_config_name = dt_name;
2203 0 : range_element.domain_info[it->first] = it->second;
2204 : } else {
2205 : // key=val domain config option
2206 0 : range_element.domain_info[it->first] = it->second;
2207 : }
2208 0 : }
2209 0 : }
2210 0 : if (this->global_transport_config_ != ACE_TEXT("")) {
2211 0 : range_element.transport_config_name = ACE_TEXT_ALWAYS_CHAR(this->global_transport_config_.c_str());
2212 : }
2213 0 : domain_ranges_.push_back(range_element);
2214 0 : }
2215 0 : }
2216 :
2217 0 : return 0;
2218 0 : }
2219 :
2220 0 : int Service_Participant::configure_domain_range_instance(DDS::DomainId_t domainId)
2221 : {
2222 0 : Discovery::RepoKey name = get_discovery_template_instance_name(domainId);
2223 :
2224 0 : if (discoveryMap_.find(name) == discoveryMap_.end()) {
2225 : // create a cf that has [rtps_discovery/name+domainId]
2226 : // copy sections adding customization
2227 0 : DomainRange dr_inst;
2228 :
2229 0 : if (get_domain_range_info(domainId, dr_inst)) {
2230 0 : ACE_Configuration_Heap dcf;
2231 0 : dcf.open();
2232 0 : const ACE_Configuration_Section_Key& root = dcf.root_section();
2233 :
2234 : // set the transport_config_name
2235 0 : domain_to_transport_name_map_[domainId] = dr_inst.transport_config_name;
2236 :
2237 : // create domain instance
2238 0 : ACE_Configuration_Section_Key dsect;
2239 0 : dcf.open_section(root, DOMAIN_SECTION_NAME, true /* create */, dsect);
2240 0 : ACE_Configuration_Section_Key dsub_sect;
2241 0 : dcf.open_section(dsect, ACE_TEXT_CHAR_TO_TCHAR(to_dds_string(domainId).c_str()), true /* create */, dsub_sect);
2242 0 : dcf.set_string_value(dsub_sect, ACE_TEXT("DiscoveryConfig"), ACE_TEXT_CHAR_TO_TCHAR(name.c_str()));
2243 0 : for (ValueMap::const_iterator it = dr_inst.domain_info.begin();
2244 0 : it != dr_inst.domain_info.end();
2245 0 : ++it) {
2246 0 : dcf.set_string_value(dsub_sect, ACE_TEXT_CHAR_TO_TCHAR(it->first.c_str()), ACE_TEXT_CHAR_TO_TCHAR(it->second.c_str()));
2247 0 : if (DCPS_debug_level > 0) {
2248 0 : ACE_DEBUG((LM_DEBUG,
2249 : ACE_TEXT("(%P|%t) Service_Participant::")
2250 : ACE_TEXT("configure_domain_range_instance(): adding %C=%C\n"),
2251 : it->first.c_str(), it->second.c_str()));
2252 : }
2253 : }
2254 :
2255 0 : ACE_TString cfg_name;
2256 0 : if (get_transport_base_config_name(domainId, cfg_name)) {
2257 0 : if (TransportRegistry::instance()->config_has_transport_template(cfg_name)) {
2258 : // create transport instance add default transport config
2259 0 : TransportRegistry::instance()->create_transport_template_instance(domainId, cfg_name);
2260 0 : const OPENDDS_STRING config_instance_name = TransportRegistry::instance()->get_config_instance_name(domainId);
2261 0 : dcf.set_string_value(dsub_sect, ACE_TEXT("DefaultTransportConfig"),
2262 : ACE_TEXT_CHAR_TO_TCHAR(config_instance_name.c_str()));
2263 0 : if (DCPS_debug_level > 0) {
2264 0 : ACE_DEBUG((LM_DEBUG,
2265 : ACE_TEXT("(%P|%t) Service_Participant::")
2266 : ACE_TEXT("configure_domain_range_instance(): setting DefaultTransportConfig=%C\n"),
2267 : config_instance_name.c_str()));
2268 : }
2269 0 : }
2270 : } else {
2271 0 : ACE_ERROR_RETURN((LM_ERROR,
2272 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::")
2273 : ACE_TEXT("configure_domain_range_instance(): ")
2274 : ACE_TEXT("transport config not found for domain %d\n"),
2275 : domainId),
2276 : -1);
2277 : }
2278 :
2279 : //create matching discovery instance
2280 0 : ACE_Configuration_Section_Key sect;
2281 0 : dcf.open_section(root, RTPS_SECTION_NAME, true /* create */, sect);
2282 0 : ACE_Configuration_Section_Key sub_sect;
2283 0 : dcf.open_section(sect, ACE_TEXT_CHAR_TO_TCHAR(name.c_str()), true, sub_sect);
2284 :
2285 0 : ValueMap discovery_settings;
2286 0 : if (process_customizations(domainId, dr_inst.discovery_template_name, discovery_settings)) {
2287 0 : for (ValueMap::const_iterator ds_it = discovery_settings.begin(); ds_it != discovery_settings.end(); ++ds_it) {
2288 0 : dcf.set_string_value(sub_sect, ACE_TEXT_CHAR_TO_TCHAR(ds_it->first.c_str()), ACE_TEXT_CHAR_TO_TCHAR(ds_it->second.c_str()));
2289 : }
2290 : }
2291 :
2292 : // load discovery
2293 0 : int status = this->load_discovery_configuration(dcf, RTPS_SECTION_NAME);
2294 :
2295 0 : if (status != 0) {
2296 0 : ACE_ERROR_RETURN((LM_ERROR,
2297 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::configure_domain_range_instance(): ")
2298 : ACE_TEXT("load_discovery_configuration() returned %d\n"),
2299 : status),
2300 : -1);
2301 : }
2302 :
2303 : // load domain config
2304 0 : status = this->load_domain_configuration(dcf, 0);
2305 :
2306 0 : if (status != 0) {
2307 0 : ACE_ERROR_RETURN((LM_ERROR,
2308 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::configure_domain_range_instance(): ")
2309 : ACE_TEXT("load_domain_configuration() returned %d\n"),
2310 : status),
2311 : -1);
2312 : }
2313 :
2314 0 : if (DCPS_debug_level > 4) {
2315 0 : ACE_DEBUG((LM_DEBUG,
2316 : ACE_TEXT("(%P|%t) Service_Participant::configure_domain_range_instance(): ")
2317 : ACE_TEXT("configure domain %d.\n"),
2318 : domainId));
2319 : }
2320 0 : }
2321 :
2322 0 : } else {
2323 : // > 9 to limit number of messages.
2324 0 : if (DCPS_debug_level > 9) {
2325 0 : ACE_DEBUG((LM_DEBUG,
2326 : ACE_TEXT("(%P|%t) Service_Participant::configure_domain_range_instance(): ")
2327 : ACE_TEXT("domain %d already configured.\n"),
2328 : domainId));
2329 : }
2330 : }
2331 0 : return 0;
2332 0 : }
2333 :
2334 :
2335 : bool
2336 0 : Service_Participant::belongs_to_domain_range(DDS::DomainId_t domainId) const
2337 : {
2338 0 : for (OPENDDS_VECTOR(DomainRange)::const_iterator i = domain_ranges_.begin(); i != domain_ranges_.end(); ++i) {
2339 0 : if (domainId >= i->range_start && domainId <= i->range_end) {
2340 0 : return true;
2341 : }
2342 : }
2343 :
2344 0 : return false;
2345 : }
2346 :
2347 : bool
2348 0 : Service_Participant::get_transport_base_config_name(DDS::DomainId_t domainId, ACE_TString& name) const
2349 : {
2350 0 : OPENDDS_MAP(DDS::DomainId_t, OPENDDS_STRING)::const_iterator it = domain_to_transport_name_map_.find(domainId);
2351 0 : if ( it != domain_to_transport_name_map_.end()) {
2352 0 : name = ACE_TEXT_CHAR_TO_TCHAR(it->second.c_str());
2353 0 : return true;
2354 0 : } else if (global_transport_config_ != ACE_TEXT("")) {
2355 0 : name = global_transport_config_;
2356 0 : return true;
2357 : } else {
2358 0 : return false;
2359 : }
2360 : }
2361 :
2362 : int
2363 0 : Service_Participant::load_discovery_configuration(ACE_Configuration_Heap& cf,
2364 : const ACE_TCHAR* section_name)
2365 : {
2366 0 : const ACE_Configuration_Section_Key &root = cf.root_section();
2367 0 : ACE_Configuration_Section_Key sect;
2368 0 : if (cf.open_section(root, section_name, false, sect) == 0) {
2369 :
2370 0 : const OPENDDS_STRING sect_name = ACE_TEXT_ALWAYS_CHAR(section_name);
2371 : DiscoveryTypes::iterator iter =
2372 0 : this->discovery_types_.find(sect_name);
2373 :
2374 0 : if (iter == this->discovery_types_.end()) {
2375 : // See if we can dynamically load the required libraries
2376 0 : TheTransportRegistry->load_transport_lib(sect_name);
2377 0 : iter = this->discovery_types_.find(sect_name);
2378 : }
2379 :
2380 0 : if (iter != this->discovery_types_.end()) {
2381 : // discovery code is loaded, process options
2382 0 : return iter->second->discovery_config(cf);
2383 : } else {
2384 : // No discovery code can be loaded, report an error
2385 0 : ACE_ERROR_RETURN((LM_ERROR,
2386 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::")
2387 : ACE_TEXT("load_discovery_configuration(): ")
2388 : ACE_TEXT("Unable to load libraries for %s\n"),
2389 : section_name),
2390 : -1);
2391 : }
2392 0 : }
2393 0 : return 0;
2394 0 : }
2395 :
2396 : int
2397 0 : Service_Participant::configure_discovery_template(DDS::DomainId_t domainId, const OPENDDS_STRING& discovery_name)
2398 : {
2399 0 : ValueMap discovery_settings;
2400 0 : if (process_customizations(domainId, discovery_name, discovery_settings)) {
2401 0 : Discovery::RepoKey name = get_discovery_template_instance_name(domainId);
2402 :
2403 0 : if (discoveryMap_.find(name) == discoveryMap_.end()) {
2404 0 : ACE_Configuration_Heap dcf;
2405 0 : dcf.open();
2406 0 : const ACE_Configuration_Section_Key& root = dcf.root_section();
2407 :
2408 : //create discovery instance
2409 0 : ACE_Configuration_Section_Key sect;
2410 0 : dcf.open_section(root, RTPS_SECTION_NAME, true /* create */, sect);
2411 0 : ACE_Configuration_Section_Key sub_sect;
2412 0 : dcf.open_section(sect, ACE_TEXT_CHAR_TO_TCHAR(name.c_str()), true, sub_sect);
2413 :
2414 0 : for (ValueMap::const_iterator ds_it = discovery_settings.begin(); ds_it != discovery_settings.end(); ++ds_it) {
2415 0 : dcf.set_string_value(sub_sect, ACE_TEXT_CHAR_TO_TCHAR(ds_it->first.c_str()), ACE_TEXT_CHAR_TO_TCHAR(ds_it->second.c_str()));
2416 0 : if (DCPS_debug_level > 0) {
2417 0 : ACE_DEBUG((LM_DEBUG,
2418 : ACE_TEXT("(%P|%t) Service_Participant::configure_discovery_template(): ")
2419 : ACE_TEXT("setting %C = %C\n"),
2420 : ds_it->first.c_str(), ds_it->second.c_str()));
2421 : }
2422 : }
2423 :
2424 : // load discovery
2425 0 : int status = this->load_discovery_configuration(dcf, RTPS_SECTION_NAME);
2426 :
2427 0 : if (status != 0) {
2428 0 : ACE_ERROR_RETURN((LM_ERROR,
2429 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::configure_discovery_template(): ")
2430 : ACE_TEXT("load_discovery_configuration() returned %d\n"),
2431 : status),
2432 : -1);
2433 : }
2434 0 : } else {
2435 : // already configured. not necessarily an error
2436 0 : if (DCPS_debug_level > 0) {
2437 0 : ACE_DEBUG((LM_DEBUG,
2438 : ACE_TEXT("(%P|%t) Discovery config %C already exists\n"),
2439 : name.c_str()));
2440 : }
2441 :
2442 : }
2443 0 : } else {
2444 0 : ACE_ERROR_RETURN((LM_ERROR,
2445 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::configure_discovery_template(): ")
2446 : ACE_TEXT("process_customizations() returned false\n")),
2447 : -1);
2448 : }
2449 :
2450 0 : return 0;
2451 0 : }
2452 :
2453 :
2454 : int
2455 0 : Service_Participant::load_discovery_templates(ACE_Configuration_Heap& cf)
2456 : {
2457 : // open the rtps_discovery config sections
2458 0 : cf.open();
2459 0 : const ACE_Configuration_Section_Key& root = cf.root_section();
2460 0 : ACE_Configuration_Section_Key rtps_sect;
2461 :
2462 0 : if (cf.open_section(root, RTPS_SECTION_NAME, false, rtps_sect) == 0) {
2463 0 : ValueMap vm;
2464 0 : if (pullValues(cf, rtps_sect, vm) > 0) {
2465 : // There are values inside [rtps_discovery]
2466 0 : ACE_ERROR_RETURN((LM_ERROR,
2467 : ACE_TEXT("(%P|%t) Service_Participant::load_discovery_templates(): ")
2468 : ACE_TEXT("rtps_discovery sections must have a subsection name\n")),
2469 : -1);
2470 : }
2471 :
2472 : // Process the subsections of this section (the individual domains)
2473 0 : KeyList keys;
2474 0 : if (processSections(cf, rtps_sect, keys) != 0) {
2475 0 : ACE_ERROR_RETURN((LM_ERROR,
2476 : ACE_TEXT("(%P|%t) Service_Participant::load_discovery_templates(): ")
2477 : ACE_TEXT("too many nesting layers in the [rtps_discovery] section.\n")),
2478 : -1);
2479 : }
2480 :
2481 : // store the discovery information
2482 0 : for (KeyList::const_iterator disc_it = keys.begin(); disc_it != keys.end(); ++disc_it) {
2483 0 : DiscoveryInfo dinfo;
2484 0 : dinfo.discovery_name = disc_it->first;
2485 :
2486 0 : ValueMap values;
2487 0 : if (pullValues(cf, disc_it->second, values) > 0) {
2488 0 : for (ValueMap::const_iterator it = values.begin(); it != values.end(); ++it) {
2489 : // check for customizations
2490 0 : if (it->first == ACE_TEXT_ALWAYS_CHAR(CUSTOMIZATION_SECTION_NAME)) {
2491 0 : OPENDDS_STRING customization = it->second;
2492 0 : if (DCPS_debug_level > 0) {
2493 0 : ACE_DEBUG((LM_DEBUG,
2494 : ACE_TEXT("(%P|%t) Service_Participant::load_discovery_templates(): ")
2495 : ACE_TEXT("loading customizations [%s/%C]\n"),
2496 : CUSTOMIZATION_SECTION_NAME,
2497 : customization.c_str()));
2498 : }
2499 :
2500 0 : ACE_Configuration_Section_Key custom_sect;
2501 0 : if (cf.open_section(root, CUSTOMIZATION_SECTION_NAME, false, custom_sect) == 0) {
2502 0 : ValueMap vcm;
2503 0 : if (pullValues(cf, custom_sect, vcm) > 0) {
2504 0 : ACE_ERROR_RETURN((LM_ERROR,
2505 : ACE_TEXT("(%P|%t) Service_Participant::load_discovery_templates(): ")
2506 : ACE_TEXT("%s sections must have a subsection name\n"),
2507 : CUSTOMIZATION_SECTION_NAME),
2508 : -1);
2509 : }
2510 :
2511 : // Process the subsections of the custom section
2512 0 : KeyList keys;
2513 0 : if (processSections(cf, custom_sect, keys) != 0) {
2514 0 : ACE_ERROR_RETURN((LM_ERROR,
2515 : ACE_TEXT("(%P|%t) Service_Participant::load_discovery_templates(): ")
2516 : ACE_TEXT("too many nesting layers in the [%s] section.\n"),
2517 : CUSTOMIZATION_SECTION_NAME),
2518 : -1);
2519 : }
2520 :
2521 : // add customizations to domain range
2522 0 : for (KeyList::const_iterator iter = keys.begin(); iter != keys.end(); ++iter) {
2523 0 : if (customization == iter->first) {
2524 0 : ValueMap values;
2525 0 : pullValues(cf, iter->second, values);
2526 0 : for (ValueMap::const_iterator it = values.begin(); it != values.end(); ++it) {
2527 0 : dinfo.customizations[it->first] = it->second;
2528 : }
2529 0 : }
2530 : }
2531 0 : }
2532 0 : } else {
2533 0 : dinfo.disc_info[it->first] = it->second;
2534 : }
2535 : }
2536 : }
2537 :
2538 0 : discovery_infos_.push_back(dinfo);
2539 0 : }
2540 0 : }
2541 :
2542 : // return 0 even if no templates were loaded
2543 0 : return 0;
2544 0 : }
2545 :
2546 0 : int Service_Participant::parse_domain_range(const OPENDDS_STRING& range, int& start, int& end) {
2547 0 : const std::size_t dash_pos = range.find("-", 0);
2548 :
2549 0 : if (dash_pos == std::string::npos || dash_pos == range.length() - 1) {
2550 0 : start = end = -1;
2551 0 : ACE_ERROR_RETURN((LM_ERROR,
2552 : ACE_TEXT("(%P|%t) Service_Participant::parse_domain_range(): ")
2553 : ACE_TEXT("%s missing '-' in [%s/%C] section.\n"),
2554 : DOMAIN_RANGE_SECTION_NAME, DOMAIN_RANGE_SECTION_NAME, range.c_str()),
2555 : -1);
2556 : }
2557 :
2558 0 : if (!convertToInteger(range.substr(0, dash_pos), start)) {
2559 0 : start = end = -1;
2560 0 : ACE_ERROR_RETURN((LM_ERROR,
2561 : ACE_TEXT("(%P|%t) Service_Participant::parse_domain_range(): ")
2562 : ACE_TEXT("Illegal integer value for start %s (%C) in [%s/%C] section.\n"),
2563 : DOMAIN_RANGE_SECTION_NAME, range.substr(0, dash_pos).c_str(),
2564 : DOMAIN_RANGE_SECTION_NAME, range.c_str()),
2565 : -1);
2566 : }
2567 0 : if (DCPS_debug_level > 0) {
2568 0 : ACE_DEBUG((LM_DEBUG,
2569 : ACE_TEXT("(%P|%t) Service_Participant::parse_domain_range(): ")
2570 : ACE_TEXT("(%P|%t) [%s/%C]: range_start == %d\n"),
2571 : DOMAIN_RANGE_SECTION_NAME,
2572 : range.c_str(), start));
2573 : }
2574 :
2575 0 : if (!convertToInteger(range.substr(dash_pos + 1), end)) {
2576 0 : ACE_ERROR_RETURN((LM_ERROR,
2577 : ACE_TEXT("(%P|%t) Service_Participant::parse_domain_range(): ")
2578 : ACE_TEXT("Illegal integer value for end %s (%C) in [%s/%C] section.\n"),
2579 : DOMAIN_RANGE_SECTION_NAME, range.substr(0, dash_pos).c_str(),
2580 : DOMAIN_RANGE_SECTION_NAME, range.c_str()),
2581 : -1);
2582 : }
2583 :
2584 0 : if (DCPS_debug_level > 0) {
2585 0 : ACE_DEBUG((LM_DEBUG,
2586 : ACE_TEXT("(%P|%t) Service_Participant::parse_domain_range(): ")
2587 : ACE_TEXT("(%P|%t) [%s/%C]: range_end == %d\n"),
2588 : DOMAIN_RANGE_SECTION_NAME, range.c_str(), end));
2589 : }
2590 :
2591 0 : if (end < start) {
2592 0 : ACE_ERROR_RETURN((LM_ERROR,
2593 : ACE_TEXT("(%P|%t) Service_Participant::parse_domain_range(): ")
2594 : ACE_TEXT("Range End %d is less than range start %d in [%s/%C] section.\n"),
2595 : end, start, DOMAIN_RANGE_SECTION_NAME, range.c_str()),
2596 : -1);
2597 : }
2598 :
2599 0 : return 0;
2600 : }
2601 :
2602 : bool
2603 0 : Service_Participant::has_domain_range() const
2604 : {
2605 0 : return !domain_ranges_.empty();
2606 : }
2607 :
2608 : bool
2609 0 : Service_Participant::get_domain_range_info(const DDS::DomainId_t id, DomainRange& inst)
2610 : {
2611 0 : if (has_domain_range()) {
2612 0 : for (OPENDDS_VECTOR(DomainRange)::iterator it = domain_ranges_.begin();
2613 0 : it != domain_ranges_.end(); ++it) {
2614 0 : if (id >= it->range_start && id <= it->range_end) {
2615 0 : inst.range_start = it->range_start;
2616 0 : inst.range_end = it->range_end;
2617 0 : inst.discovery_template_name = it->discovery_template_name;
2618 0 : inst.transport_config_name = it->transport_config_name;
2619 0 : inst.domain_info = it->domain_info;
2620 :
2621 0 : if (DCPS_debug_level > 0) {
2622 0 : ACE_DEBUG((LM_DEBUG,
2623 : ACE_TEXT("(%P|%t) Service_Participant::get_domain_range_info(): ")
2624 : ACE_TEXT("Domain %d is in [%s/%d-%d]\n"),
2625 : id, DOMAIN_RANGE_SECTION_NAME, it->range_start, it->range_end));
2626 : }
2627 :
2628 0 : return true;
2629 : }
2630 : }
2631 : }
2632 0 : return false;
2633 : }
2634 :
2635 : bool
2636 0 : Service_Participant::process_customizations(DDS::DomainId_t id, const OPENDDS_STRING& discovery_name, ValueMap& customs)
2637 : {
2638 : // get the discovery info
2639 0 : OPENDDS_VECTOR(DiscoveryInfo)::const_iterator dit;
2640 0 : for (dit = discovery_infos_.begin(); dit != discovery_infos_.end(); ++dit) {
2641 0 : if (discovery_name == dit->discovery_name) {
2642 0 : break;
2643 : }
2644 : }
2645 :
2646 0 : if (dit != discovery_infos_.end()) {
2647 : // add discovery info to customs
2648 0 : for (ValueMap::const_iterator i = dit->disc_info.begin(); i != dit->disc_info.end(); ++i) {
2649 0 : customs[i->first] = i->second;
2650 0 : if (DCPS_debug_level > 0) {
2651 0 : ACE_DEBUG((LM_DEBUG,
2652 : ACE_TEXT("(%P|%t) Service_Participant::")
2653 : ACE_TEXT("process_customizations(): adding config %C=%C\n"),
2654 : i->first.c_str(), i->second.c_str()));
2655 : }
2656 : }
2657 :
2658 : // update customs valuemap with any customizations
2659 0 : for (ValueMap::const_iterator i = dit->customizations.begin(); i != dit->customizations.end(); ++i) {
2660 0 : if (i->first == "InteropMulticastOverride" && i->second == "AddDomainId") {
2661 0 : OPENDDS_STRING addr = customs["InteropMulticastOverride"];
2662 0 : size_t pos = addr.find_last_of(".");
2663 0 : if (pos != OPENDDS_STRING::npos) {
2664 0 : OPENDDS_STRING custom = addr.substr(pos + 1);
2665 0 : int val = 0;
2666 0 : if (!convertToInteger(custom, val)) {
2667 0 : ACE_ERROR_RETURN((LM_ERROR,
2668 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::")
2669 : ACE_TEXT("process_customizations(): ")
2670 : ACE_TEXT("could not convert %C to integer\n"),
2671 : custom.c_str()),
2672 : false);
2673 : }
2674 0 : val += id;
2675 0 : addr = addr.substr(0, pos);
2676 0 : addr += "." + to_dds_string(val);
2677 0 : } else {
2678 0 : ACE_ERROR_RETURN((LM_ERROR,
2679 : ACE_TEXT("(%P|%t) ERROR: Service_Participant::")
2680 : ACE_TEXT("process_customizations(): ")
2681 : ACE_TEXT("could not AddDomainId for %s\n"),
2682 : customs["InteropMulticastOverride"].c_str()),
2683 : false);
2684 : }
2685 :
2686 0 : customs["InteropMulticastOverride"] = addr;
2687 0 : }
2688 : }
2689 : }
2690 :
2691 0 : return true;
2692 : }
2693 :
2694 : Discovery::RepoKey
2695 0 : Service_Participant::get_discovery_template_instance_name(const DDS::DomainId_t id)
2696 : {
2697 0 : OpenDDS::DCPS::Discovery::RepoKey configured_name = "rtps_template_instance_";
2698 0 : configured_name += to_dds_string(id);
2699 0 : return configured_name;
2700 0 : }
2701 :
2702 : bool
2703 0 : Service_Participant::is_discovery_template(const OPENDDS_STRING& name)
2704 : {
2705 0 : OPENDDS_VECTOR(DiscoveryInfo)::const_iterator i;
2706 0 : for (i = discovery_infos_.begin(); i != discovery_infos_.end(); ++i) {
2707 0 : if (i->discovery_name == name && !i->customizations.empty()) {
2708 0 : return true;
2709 : }
2710 : }
2711 :
2712 0 : return false;
2713 : }
2714 :
2715 : #if OPENDDS_POOL_ALLOCATOR
2716 : void
2717 : Service_Participant::configure_pool()
2718 : {
2719 : if (pool_size_) {
2720 : SafetyProfilePool::instance()->configure_pool(pool_size_, pool_granularity_);
2721 : SafetyProfilePool::instance()->install();
2722 : }
2723 : }
2724 : #endif
2725 :
2726 : #ifndef OPENDDS_NO_PERSISTENCE_PROFILE
2727 : DataDurabilityCache *
2728 0 : Service_Participant::get_data_durability_cache(
2729 : DDS::DurabilityQosPolicy const & durability)
2730 : {
2731 0 : DDS::DurabilityQosPolicyKind const kind =
2732 : durability.kind;
2733 :
2734 0 : DataDurabilityCache * cache = 0;
2735 :
2736 0 : if (kind == DDS::TRANSIENT_DURABILITY_QOS) {
2737 : {
2738 0 : ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, factory_lock_, 0);
2739 :
2740 0 : if (!this->transient_data_cache_) {
2741 0 : this->transient_data_cache_.reset(new DataDurabilityCache(kind));
2742 : }
2743 0 : }
2744 :
2745 0 : cache = this->transient_data_cache_.get();
2746 :
2747 0 : } else if (kind == DDS::PERSISTENT_DURABILITY_QOS) {
2748 : {
2749 0 : ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, factory_lock_, 0);
2750 :
2751 : try {
2752 0 : if (!this->persistent_data_cache_) {
2753 0 : this->persistent_data_cache_.reset(new DataDurabilityCache(kind,
2754 0 : this->persistent_data_dir_));
2755 : }
2756 :
2757 0 : } catch (const std::exception& ex) {
2758 0 : if (DCPS_debug_level > 0) {
2759 0 : ACE_ERROR((LM_WARNING,
2760 : ACE_TEXT("(%P|%t) WARNING: Service_Participant::get_data_durability_cache ")
2761 : ACE_TEXT("failed to create PERSISTENT cache, falling back on ")
2762 : ACE_TEXT("TRANSIENT behavior: %C\n"), ex.what()));
2763 : }
2764 :
2765 0 : this->persistent_data_cache_.reset(new DataDurabilityCache(DDS::TRANSIENT_DURABILITY_QOS));
2766 0 : }
2767 0 : }
2768 :
2769 0 : cache = this->persistent_data_cache_.get();
2770 : }
2771 :
2772 0 : return cache;
2773 : }
2774 : #endif
2775 :
2776 : void
2777 0 : Service_Participant::add_discovery(Discovery_rch discovery)
2778 : {
2779 0 : if (discovery) {
2780 0 : ACE_GUARD(ACE_Recursive_Thread_Mutex, guard, this->maps_lock_);
2781 0 : this->discoveryMap_[discovery->key()] = discovery;
2782 0 : }
2783 : }
2784 :
2785 : void
2786 0 : Service_Participant::set_shutdown_listener(RcHandle<ShutdownListener> listener)
2787 : {
2788 0 : shutdown_listener_ = listener;
2789 0 : }
2790 :
2791 : const Service_Participant::RepoKeyDiscoveryMap&
2792 0 : Service_Participant::discoveryMap() const
2793 : {
2794 0 : return this->discoveryMap_;
2795 : }
2796 :
2797 : const Service_Participant::DomainRepoMap&
2798 0 : Service_Participant::domainRepoMap() const
2799 : {
2800 0 : return this->domainRepoMap_;
2801 : }
2802 :
2803 : Recorder_ptr
2804 0 : Service_Participant::create_recorder(DDS::DomainParticipant_ptr participant,
2805 : DDS::Topic_ptr a_topic,
2806 : const DDS::SubscriberQos& subscriber_qos,
2807 : const DDS::DataReaderQos& datareader_qos,
2808 : const RecorderListener_rch& a_listener)
2809 : {
2810 0 : DomainParticipantImpl* participant_servant = dynamic_cast<DomainParticipantImpl*>(participant);
2811 0 : if (participant_servant)
2812 0 : return participant_servant->create_recorder(a_topic, subscriber_qos, datareader_qos, a_listener, 0);
2813 0 : return 0;
2814 : }
2815 :
2816 : DDS::ReturnCode_t
2817 0 : Service_Participant::delete_recorder(Recorder_ptr recorder)
2818 : {
2819 0 : DDS::ReturnCode_t ret = DDS::RETCODE_ERROR;
2820 0 : RecorderImpl* impl = dynamic_cast<RecorderImpl*>(recorder);
2821 0 : if (impl){
2822 0 : ret = impl->cleanup();
2823 0 : impl->participant()->delete_recorder(recorder);
2824 : }
2825 0 : return ret;
2826 : }
2827 :
2828 : Replayer_ptr
2829 0 : Service_Participant::create_replayer(DDS::DomainParticipant_ptr participant,
2830 : DDS::Topic_ptr a_topic,
2831 : const DDS::PublisherQos& publisher_qos,
2832 : const DDS::DataWriterQos& datawriter_qos,
2833 : const ReplayerListener_rch& a_listener)
2834 : {
2835 0 : DomainParticipantImpl* participant_servant = dynamic_cast<DomainParticipantImpl*>(participant);
2836 0 : if (participant_servant)
2837 0 : return participant_servant->create_replayer(a_topic, publisher_qos, datawriter_qos, a_listener, 0);
2838 0 : return 0;
2839 : }
2840 :
2841 : DDS::ReturnCode_t
2842 0 : Service_Participant::delete_replayer(Replayer_ptr replayer)
2843 : {
2844 0 : DDS::ReturnCode_t ret = DDS::RETCODE_ERROR;
2845 0 : ReplayerImpl* impl = static_cast<ReplayerImpl*>(replayer);
2846 0 : if (impl) {
2847 0 : ret = impl->cleanup();
2848 0 : impl->participant()->delete_replayer(replayer);
2849 : }
2850 0 : return ret;
2851 : }
2852 :
2853 0 : DDS::Topic_ptr Service_Participant::create_typeless_topic(
2854 : DDS::DomainParticipant_ptr participant,
2855 : const char* topic_name,
2856 : const char* type_name,
2857 : bool type_has_keys,
2858 : const DDS::TopicQos& qos,
2859 : DDS::TopicListener_ptr a_listener,
2860 : DDS::StatusMask mask)
2861 : {
2862 0 : DomainParticipantImpl* participant_servant = dynamic_cast<DomainParticipantImpl*>(participant);
2863 0 : if (!participant_servant) {
2864 0 : return 0;
2865 : }
2866 0 : return participant_servant->create_typeless_topic(topic_name, type_name, type_has_keys, qos, a_listener, mask);
2867 : }
2868 :
2869 0 : void Service_Participant::default_configuration_file(const ACE_TCHAR* path)
2870 : {
2871 0 : default_configuration_file_ = path;
2872 0 : }
2873 :
2874 495 : ThreadStatusManager& Service_Participant::get_thread_status_manager()
2875 : {
2876 495 : return thread_status_manager_;
2877 : }
2878 :
2879 1088 : ACE_Thread_Mutex& Service_Participant::get_static_xtypes_lock()
2880 : {
2881 1088 : return xtypes_lock_;
2882 : }
2883 :
2884 : #ifdef OPENDDS_NETWORK_CONFIG_MODIFIER
2885 : NetworkConfigModifier* Service_Participant::network_config_modifier()
2886 : {
2887 : return dynamic_cast<NetworkConfigModifier*>(network_config_monitor_.get());
2888 : }
2889 : #endif
2890 :
2891 : DDS::Duration_t
2892 0 : Service_Participant::bit_autopurge_nowriter_samples_delay() const
2893 : {
2894 0 : return bit_autopurge_nowriter_samples_delay_;
2895 : }
2896 :
2897 : void
2898 0 : Service_Participant::bit_autopurge_nowriter_samples_delay(const DDS::Duration_t& duration)
2899 : {
2900 0 : bit_autopurge_nowriter_samples_delay_ = duration;
2901 0 : }
2902 :
2903 : DDS::Duration_t
2904 0 : Service_Participant::bit_autopurge_disposed_samples_delay() const
2905 : {
2906 0 : return bit_autopurge_disposed_samples_delay_;
2907 : }
2908 :
2909 : void
2910 0 : Service_Participant::bit_autopurge_disposed_samples_delay(const DDS::Duration_t& duration)
2911 : {
2912 0 : bit_autopurge_disposed_samples_delay_ = duration;
2913 0 : }
2914 :
2915 : XTypes::TypeInformation
2916 0 : Service_Participant::get_type_information(DDS::DomainParticipant_ptr participant,
2917 : const DDS::BuiltinTopicKey_t& key) const
2918 : {
2919 0 : DomainParticipantImpl* participant_servant = dynamic_cast<DomainParticipantImpl*>(participant);
2920 0 : if (participant_servant) {
2921 0 : XTypes::TypeLookupService_rch tls = participant_servant->get_type_lookup_service();
2922 0 : if (tls) {
2923 0 : return tls->get_type_info(key);
2924 : }
2925 0 : }
2926 :
2927 0 : return XTypes::TypeInformation();
2928 : }
2929 :
2930 : #ifndef OPENDDS_SAFETY_PROFILE
2931 0 : DDS::ReturnCode_t Service_Participant::get_dynamic_type(DDS::DynamicType_var& type,
2932 : DDS::DomainParticipant_ptr participant, const DDS::BuiltinTopicKey_t& key) const
2933 : {
2934 0 : return dynamic_cast<DomainParticipantImpl*>(participant)->get_dynamic_type(type, key);
2935 : }
2936 : #endif
2937 :
2938 : XTypes::TypeObject
2939 0 : Service_Participant::get_type_object(DDS::DomainParticipant_ptr participant,
2940 : const XTypes::TypeIdentifier& ti) const
2941 : {
2942 0 : DomainParticipantImpl* participant_servant = dynamic_cast<DomainParticipantImpl*>(participant);
2943 0 : if (participant_servant) {
2944 0 : XTypes::TypeLookupService_rch tls = participant_servant->get_type_lookup_service();
2945 0 : if (tls) {
2946 0 : return tls->get_type_object(ti);
2947 : }
2948 0 : }
2949 :
2950 0 : return XTypes::TypeObject();
2951 : }
2952 :
2953 : void
2954 0 : Service_Participant::type_object_encoding(const char* encoding)
2955 : {
2956 : struct NameValue {
2957 : const char* name;
2958 : TypeObjectEncoding value;
2959 : };
2960 : static const NameValue entries[] = {
2961 : {"Normal", Encoding_Normal},
2962 : {"WriteOldFormat", Encoding_WriteOldFormat},
2963 : {"ReadOldFormat", Encoding_ReadOldFormat},
2964 : };
2965 0 : for (size_t i = 0; i < sizeof entries / sizeof entries[0]; ++i) {
2966 0 : if (0 == std::strcmp(entries[i].name, encoding)) {
2967 0 : type_object_encoding(entries[i].value);
2968 0 : return;
2969 : }
2970 : }
2971 0 : ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: Service_Participant::type_object_encoding: "
2972 : "invalid encoding %C\n", encoding));
2973 : }
2974 :
2975 : } // namespace DCPS
2976 : } // namespace OpenDDS
2977 :
2978 : OPENDDS_END_VERSIONED_NAMESPACE_DECL
|