LCOV - code coverage report
Current view: top level - DCPS/transport/framework - TransportRegistry.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 30 536 5.6 %
Date: 2023-04-30 01:32:43 Functions: 4 29 13.8 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  *
       4             :  * Distributed under the OpenDDS License.
       5             :  * See: http://www.opendds.org/license.html
       6             :  */
       7             : 
       8             : #include "DCPS/DdsDcps_pch.h" //Only the _pch include should start with DCPS/
       9             : #include "TransportRegistry.h"
      10             : #include "TransportDebug.h"
      11             : #include "TransportInst.h"
      12             : #include "TransportExceptions.h"
      13             : #include "TransportType.h"
      14             : #include "dds/DCPS/GuidConverter.h"
      15             : #include "dds/DCPS/Util.h"
      16             : #include "dds/DCPS/Service_Participant.h"
      17             : #include "dds/DCPS/EntityImpl.h"
      18             : #include "dds/DCPS/SafetyProfileStreams.h"
      19             : #include <dds/DdsDcpsInfrastructureC.h>
      20             : 
      21             : 
      22             : #include "ace/Singleton.h"
      23             : #include "ace/OS_NS_strings.h"
      24             : #include "ace/Service_Config.h"
      25             : 
      26             : #if !defined (__ACE_INLINE__)
      27             : #include "TransportRegistry.inl"
      28             : #endif /* __ACE_INLINE__ */
      29             : 
      30             : 
      31             : namespace {
      32             :   /// Used for sorting
      33           0 :   bool predicate(const OpenDDS::DCPS::TransportInst_rch& lhs,
      34             :                  const OpenDDS::DCPS::TransportInst_rch& rhs)
      35             :   {
      36           0 :     return lhs->name() < rhs->name();
      37             :   }
      38             : 
      39             :   // transport type to try loading if none are loaded when DCPS attempts to use
      40             : #ifdef OPENDDS_SAFETY_PROFILE
      41             :   const char FALLBACK_TYPE[] = "rtps_udp";
      42             : #else
      43             :   const char FALLBACK_TYPE[] = "tcp";
      44             : #endif
      45             : }
      46             : 
      47             : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
      48             : 
      49             : namespace OpenDDS {
      50             : namespace DCPS {
      51             : 
      52             : TransportRegistry*
      53           9 : TransportRegistry::instance()
      54             : {
      55           9 :   return ACE_Unmanaged_Singleton<TransportRegistry, ACE_Recursive_Thread_Mutex>::instance();
      56             : }
      57             : 
      58             : void
      59           9 : TransportRegistry::close()
      60             : {
      61           9 :   ACE_Unmanaged_Singleton<TransportRegistry, ACE_Recursive_Thread_Mutex>::close();
      62           9 : }
      63             : 
      64             : const char TransportRegistry::DEFAULT_CONFIG_NAME[] = "_OPENDDS_DEFAULT_CONFIG";
      65             : const char TransportRegistry::DEFAULT_INST_PREFIX[] = "_OPENDDS_";
      66             : 
      67             : // transport template customizations
      68             : const OPENDDS_STRING TransportRegistry::CUSTOM_ADD_DOMAIN_TO_IP = "add_domain_id_to_ip_addr";
      69             : const OPENDDS_STRING TransportRegistry::CUSTOM_ADD_DOMAIN_TO_PORT = "add_domain_id_to_port";
      70             : 
      71           9 : TransportRegistry::TransportRegistry()
      72           9 :   : global_config_(make_rch<TransportConfig>(DEFAULT_CONFIG_NAME))
      73          18 :   , released_(false)
      74             : {
      75             :   DBG_ENTRY_LVL("TransportRegistry", "TransportRegistry", 6);
      76           9 :   config_map_[DEFAULT_CONFIG_NAME] = global_config_;
      77             : 
      78           9 :   lib_directive_map_["tcp"]       = "dynamic OpenDDS_Tcp Service_Object * OpenDDS_Tcp:_make_TcpLoader()";
      79           9 :   lib_directive_map_["udp"]       = "dynamic OpenDDS_Udp Service_Object * OpenDDS_Udp:_make_UdpLoader()";
      80           9 :   lib_directive_map_["multicast"] = "dynamic OpenDDS_Multicast Service_Object * OpenDDS_Multicast:_make_MulticastLoader()";
      81           9 :   lib_directive_map_["rtps_udp"]  = "dynamic OpenDDS_Rtps_Udp Service_Object * OpenDDS_Rtps_Udp:_make_RtpsUdpLoader()";
      82           9 :   lib_directive_map_["shmem"]     = "dynamic OpenDDS_Shmem Service_Object * OpenDDS_Shmem:_make_ShmemLoader()";
      83             : 
      84             :   // load_transport_lib() is used for discovery as well:
      85           9 :   lib_directive_map_["rtps_discovery"] = lib_directive_map_["rtps_udp"];
      86           9 :   lib_directive_map_["repository"] = "dynamic OpenDDS_InfoRepoDiscovery Service_Object * OpenDDS_InfoRepoDiscovery:_make_IRDiscoveryLoader()";
      87           9 : }
      88             : 
      89             : int
      90           0 : TransportRegistry::load_transport_configuration(const OPENDDS_STRING& file_name,
      91             :                                                 ACE_Configuration_Heap& cf)
      92             : {
      93           0 :   const ACE_Configuration_Section_Key& root = cf.root_section();
      94             : 
      95             :   // Create a vector to hold configuration information so we can populate
      96             :   // them after the transports instances are created.
      97             :   typedef std::pair<TransportConfig_rch, OPENDDS_VECTOR(OPENDDS_STRING) > ConfigInfo;
      98           0 :   OPENDDS_VECTOR(ConfigInfo) configInfoVec;
      99             : 
     100             :   // Record the transport instances created, so we can place them
     101             :   // in the implicit transport configuration for this file.
     102           0 :   OPENDDS_LIST(TransportInst_rch) instances;
     103             : 
     104           0 :   ACE_TString sect_name;
     105             : 
     106           0 :   for (int index = 0;
     107           0 :        cf.enumerate_sections(root, index, sect_name) == 0;
     108             :        ++index) {
     109           0 :     if (ACE_OS::strcmp(sect_name.c_str(), TRANSPORT_SECTION_NAME) == 0 ||
     110           0 :         ACE_OS::strcmp(sect_name.c_str(), TRANSPORT_TEMPLATE_SECTION_NAME) == 0) {
     111             :       // found the [transport/*] or [transport_template/*] section,
     112             :       // now iterate through subsections...
     113           0 :       ACE_Configuration_Section_Key sect;
     114           0 :       if (cf.open_section(root, sect_name.c_str(), false, sect) != 0) {
     115           0 :         ACE_ERROR_RETURN((LM_ERROR,
     116             :                           ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ")
     117             :                           ACE_TEXT("failed to open section %C\n"),
     118             :                           sect_name.c_str()),
     119             :                          -1);
     120             :       } else {
     121             :         // Ensure there are no properties in this section
     122           0 :         ValueMap vm;
     123           0 :         if (pullValues(cf, sect, vm) > 0) {
     124             :           // There are values inside [transport]
     125           0 :           ACE_ERROR_RETURN((LM_ERROR,
     126             :                             ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ")
     127             :                             ACE_TEXT("transport sections must have a section name\n"),
     128             :                             sect_name.c_str()),
     129             :                            -1);
     130             :         }
     131             :         // Process the subsections of this section (the individual transport
     132             :         // impls).
     133           0 :         KeyList keys;
     134           0 :         if (processSections(cf, sect, keys) != 0) {
     135           0 :           ACE_ERROR_RETURN((LM_ERROR,
     136             :                             ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ")
     137             :                             ACE_TEXT("too many nesting layers in [%C] section.\n"),
     138             :                             sect_name.c_str()),
     139             :                            -1);
     140             :         }
     141           0 :         for (KeyList::const_iterator it = keys.begin(); it != keys.end(); ++it) {
     142           0 :           ACE_TString transport_id = ACE_TEXT_CHAR_TO_TCHAR(it->first.c_str());
     143           0 :           ACE_Configuration_Section_Key inst_sect = it->second;
     144             : 
     145           0 :           ValueMap values;
     146           0 :           if (pullValues(cf, it->second, values) != 0) {
     147             :             // Get the factory_id for the transport.
     148           0 :             OPENDDS_STRING transport_type;
     149           0 :             ValueMap::const_iterator vm_it = values.find("transport_type");
     150           0 :             if (vm_it != values.end()) {
     151           0 :               transport_type = vm_it->second;
     152             :             } else {
     153           0 :               ACE_ERROR_RETURN((LM_ERROR,
     154             :                                 ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ")
     155             :                                 ACE_TEXT("missing transport_type in [transport/%C] section.\n"),
     156             :                                 transport_id.c_str()),
     157             :                                -1);
     158             :             }
     159             : 
     160             :             // Create the TransportInst object and load the transport
     161             :             // configuration in ACE_Configuration_Heap to the TransportInst
     162             :             // object.
     163           0 :             const OPENDDS_STRING tid_str = transport_id.c_str() ? ACE_TEXT_ALWAYS_CHAR(transport_id.c_str()) : "";
     164           0 :             TransportInst_rch inst = create_inst(tid_str, transport_type);
     165           0 :             if (!inst) {
     166           0 :               ACE_ERROR_RETURN((LM_ERROR,
     167             :                                 ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ")
     168             :                                 ACE_TEXT("Unable to create transport instance in [transport/%C] section.\n"),
     169             :                                 transport_id.c_str()),
     170             :                                -1);
     171             :             }
     172             : 
     173           0 :             instances.push_back(inst);
     174           0 :             inst->load(cf, inst_sect);
     175             : 
     176             :             // store the transport info
     177           0 :             TransportEntry entry;
     178           0 :             entry.transport_name = transport_id;
     179           0 :             entry.transport_info = values;
     180           0 :             transports_.push_back(entry);
     181           0 :           } else {
     182           0 :             ACE_ERROR_RETURN((LM_ERROR,
     183             :                               ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ")
     184             :                               ACE_TEXT("missing transport_type in [transport/%C] section.\n"),
     185             :                               transport_id.c_str()),
     186             :                              -1);
     187             :           }
     188           0 :         }
     189           0 :       }
     190           0 :     } else if (ACE_OS::strcmp(sect_name.c_str(), CONFIG_SECTION_NAME) == 0) {
     191             :       // found the [config/*] section, now iterate through subsections...
     192           0 :       ACE_Configuration_Section_Key sect;
     193           0 :       if (cf.open_section(root, sect_name.c_str(), false, sect) != 0) {
     194           0 :         ACE_ERROR_RETURN((LM_ERROR,
     195             :                           ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ")
     196             :                           ACE_TEXT("failed to open section [%C]\n"),
     197             :                           sect_name.c_str()),
     198             :                          -1);
     199             :       } else {
     200             :         // Ensure there are no properties in this section
     201           0 :         ValueMap vm;
     202           0 :         if (pullValues(cf, sect, vm) > 0) {
     203             :           // There are values inside [config]
     204           0 :           ACE_ERROR_RETURN((LM_ERROR,
     205             :                             ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ")
     206             :                             ACE_TEXT("config sections must have a section name\n"),
     207             :                             sect_name.c_str()),
     208             :                            -1);
     209             :         }
     210             :         // Process the subsections of this section (the individual config
     211             :         // impls).
     212           0 :         KeyList keys;
     213           0 :         if (processSections(cf, sect, keys) != 0) {
     214             :           // Don't allow multiple layers of nesting ([config/x/y]).
     215           0 :           ACE_ERROR_RETURN((LM_ERROR,
     216             :                             ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ")
     217             :                             ACE_TEXT("too many nesting layers in [%C] section.\n"),
     218             :                             sect_name.c_str()),
     219             :                            -1);
     220             :         }
     221           0 :         for (KeyList::const_iterator it = keys.begin(); it != keys.end(); ++it) {
     222           0 :           OPENDDS_STRING config_id = it->first;
     223             : 
     224             :           // Create a TransportConfig object.
     225           0 :           TransportConfig_rch config = create_config(config_id);
     226           0 :           if (!config) {
     227           0 :             ACE_ERROR_RETURN((LM_ERROR,
     228             :                               ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ")
     229             :                               ACE_TEXT("Unable to create transport config in [config/%C] section.\n"),
     230             :                               config_id.c_str()),
     231             :                              -1);
     232             :           }
     233             : 
     234           0 :           ValueMap values;
     235           0 :           pullValues(cf, it->second, values);
     236             : 
     237           0 :           ConfigInfo configInfo;
     238           0 :           configInfo.first = config;
     239           0 :           for (ValueMap::const_iterator it = values.begin(); it != values.end(); ++it) {
     240           0 :             OPENDDS_STRING name = it->first;
     241           0 :             OPENDDS_STRING value = it->second;
     242           0 :             if (name == "transports") {
     243           0 :               char delim = ',';
     244           0 :               size_t pos = 0;
     245           0 :               OPENDDS_STRING token;
     246           0 :               while ((pos = value.find(delim)) != OPENDDS_STRING::npos) {
     247           0 :                 token = value.substr(0, pos);
     248           0 :                 configInfo.second.push_back(token);
     249           0 :                 value.erase(0, pos + 1);
     250             :               }
     251             : 
     252             :               // does this config specify a transport_template?
     253           0 :               for (OPENDDS_VECTOR(TransportTemplate)::iterator it = transport_templates_.begin(); it != transport_templates_.end(); ++it) {
     254           0 :                 if (it->transport_template_name == value) {
     255           0 :                   it->config_name = config_id;
     256           0 :                   break;
     257             :                 }
     258             :               }
     259             : 
     260             :               // store the config name for the transport entry
     261           0 :               for (OPENDDS_VECTOR(TransportEntry)::iterator it = transports_.begin(); it != transports_.end(); ++it) {
     262           0 :                 if (!ACE_OS::strcmp(ACE_TEXT_ALWAYS_CHAR(it->transport_name.c_str()), value.c_str())) {
     263           0 :                   it->config_name = ACE_TEXT_CHAR_TO_TCHAR(config_id.c_str());
     264           0 :                   break;
     265             :                 }
     266             :               }
     267             : 
     268           0 :               configInfo.second.push_back(value);
     269             : 
     270           0 :               configInfoVec.push_back(configInfo);
     271           0 :             } else if (name == "swap_bytes") {
     272           0 :               if ((value == "1") || (value == "true")) {
     273           0 :                 config->swap_bytes_ = true;
     274           0 :               } else if ((value != "0") && (value != "false")) {
     275           0 :                 ACE_ERROR_RETURN((LM_ERROR,
     276             :                                   ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ")
     277             :                                   ACE_TEXT("Illegal value for swap_bytes (%C) in [config/%C] section.\n"),
     278             :                                   value.c_str(), config_id.c_str()),
     279             :                                  -1);
     280             :               }
     281           0 :             } else if (name == "passive_connect_duration") {
     282           0 :               if (!convertToInteger(value,
     283           0 :                                     config->passive_connect_duration_)) {
     284           0 :                 ACE_ERROR_RETURN((LM_ERROR,
     285             :                                   ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ")
     286             :                                   ACE_TEXT("Illegal integer value for passive_connect_duration (%C) in [config/%C] section.\n"),
     287             :                                   value.c_str(), config_id.c_str()),
     288             :                                  -1);
     289             :               }
     290             :             } else {
     291           0 :               ACE_ERROR_RETURN((LM_ERROR,
     292             :                                 ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ")
     293             :                                 ACE_TEXT("Unexpected entry (%C) in [config/%C] section.\n"),
     294             :                                 name.c_str(), config_id.c_str()),
     295             :                                -1);
     296             :             }
     297           0 :           }
     298           0 :           if (configInfo.second.empty()) {
     299           0 :             ACE_ERROR_RETURN((LM_ERROR,
     300             :                               ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ")
     301             :                               ACE_TEXT("No transport instances listed in [config/%C] section.\n"),
     302             :                               config_id.c_str()),
     303             :                              -1);
     304             :           }
     305           0 :         }
     306           0 :       }
     307           0 :     }
     308             :   }
     309             : 
     310             :   // Populate the configurations with instances
     311           0 :   for (unsigned int i = 0; i < configInfoVec.size(); ++i) {
     312           0 :     TransportConfig_rch config = configInfoVec[i].first;
     313           0 :     OPENDDS_VECTOR(OPENDDS_STRING)& insts = configInfoVec[i].second;
     314           0 :     for (unsigned int j = 0; j < insts.size(); ++j) {
     315           0 :       TransportInst_rch inst = get_inst(insts[j]);
     316           0 :       if (!inst) {
     317           0 :         ACE_ERROR_RETURN((LM_ERROR,
     318             :                           ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ")
     319             :                           ACE_TEXT("The inst (%C) in [config/%C] section is undefined.\n"),
     320             :                           insts[j].c_str(), config->name().c_str()),
     321             :                          -1);
     322             :       }
     323           0 :       config->instances_.push_back(inst);
     324           0 :     }
     325           0 :   }
     326             : 
     327             :   // Create and populate the default configuration for this
     328             :   // file with all the instances from this file.
     329           0 :   if (!instances.empty()) {
     330           0 :     TransportConfig_rch config = create_config(file_name);
     331           0 :     if (!config) {
     332           0 :       ACE_ERROR_RETURN((LM_ERROR,
     333             :                         ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ")
     334             :                         ACE_TEXT("Unable to create default transport config.\n"),
     335             :                         file_name.c_str()),
     336             :                        -1);
     337             :     }
     338           0 :     instances.sort(predicate);
     339           0 :     for (OPENDDS_LIST(TransportInst_rch)::const_iterator it = instances.begin();
     340           0 :          it != instances.end(); ++it) {
     341           0 :       config->instances_.push_back(*it);
     342             :     }
     343           0 :   }
     344             : 
     345           0 :   return 0;
     346           0 : }
     347             : 
     348             : int
     349           0 : TransportRegistry::load_transport_templates(ACE_Configuration_Heap& cf)
     350             : {
     351           0 :   const ACE_Configuration_Section_Key& root = cf.root_section();
     352           0 :   ACE_Configuration_Section_Key transport_sect;
     353             : 
     354           0 :   if (cf.open_section(root, TRANSPORT_TEMPLATE_SECTION_NAME, false, transport_sect) != 0) {
     355           0 :     if (DCPS_debug_level > 0) {
     356             :       // This is not an error if the configuration file does not have
     357             :       // any domain range (sub)section.
     358           0 :       ACE_DEBUG((LM_NOTICE,
     359             :                  ACE_TEXT("(%P|%t) NOTICE: TransportRegistry::load_transport_templates(): ")
     360             :                  ACE_TEXT("config does not have a [%s] section.\n"),
     361             :                  TRANSPORT_TEMPLATE_SECTION_NAME));
     362             :     }
     363             : 
     364           0 :     return 0;
     365             : 
     366             :   } else {
     367           0 :     if (DCPS_debug_level > 0) {
     368           0 :       ACE_DEBUG((LM_NOTICE,
     369             :                    ACE_TEXT("(%P|%t) NOTICE: TransportRegistry::load_transport_templates(): ")
     370             :                    ACE_TEXT("config has %s sections.\n"),
     371             :                    TRANSPORT_TEMPLATE_SECTION_NAME));
     372             :     }
     373             : 
     374             :     // Ensure there are no properties in this section
     375           0 :     ValueMap vm;
     376           0 :     if (pullValues(cf, transport_sect, vm) > 0) {
     377             :       // There are values inside [transport_template]
     378           0 :       ACE_ERROR_RETURN((LM_ERROR,
     379             :                         ACE_TEXT("(%P|%t) ERROR: TransportRegistry::load_transport_templates(): ")
     380             :                         ACE_TEXT("%s sections must have a subsection name\n"),
     381             :                         TRANSPORT_TEMPLATE_SECTION_NAME),
     382             :                      -1);
     383             :     }
     384             :     // Process the subsections of this section (the individual domains)
     385           0 :     KeyList keys;
     386           0 :     if (processSections(cf, transport_sect, keys) != 0) {
     387           0 :       ACE_ERROR_RETURN((LM_ERROR,
     388             :                         ACE_TEXT("(%P|%t) ERROR: TransportRegistry::load_transport_templates(): ")
     389             :                         ACE_TEXT("too many nesting layers in the [%s] section.\n"),
     390             :                         TRANSPORT_TEMPLATE_SECTION_NAME),
     391             :                        -1);
     392             :     }
     393             : 
     394             :     // Loop through the [transport_template/*] sections
     395           0 :     for (KeyList::const_iterator it = keys.begin(); it != keys.end(); ++it) {
     396           0 :       TransportTemplate element;
     397           0 :       element.instantiate_per_participant = false;
     398           0 :       element.transport_template_name = it->first;
     399             : 
     400           0 :       if (DCPS_debug_level > 0) {
     401           0 :         ACE_DEBUG((LM_DEBUG,
     402             :                    ACE_TEXT("(%P|%t) TransportRegistry::load_transport_templates(): ")
     403             :                    ACE_TEXT("processing [%s/%C]\n"),
     404             :                    TRANSPORT_TEMPLATE_SECTION_NAME, element.transport_template_name.c_str()));
     405             :       }
     406             : 
     407           0 :       ValueMap values;
     408           0 :       pullValues(cf, it->second, values);
     409           0 :       OPENDDS_STRING rule;
     410           0 :       OPENDDS_STRING customization;
     411             : 
     412           0 :       for (ValueMap::const_iterator it = values.begin(); it != values.end(); ++it) {
     413           0 :         OPENDDS_STRING name = it->first;
     414           0 :         if (name == "instantiation_rule") {
     415           0 :           rule = it->second;
     416           0 :           if (rule == "per_participant") {
     417           0 :             element.instantiate_per_participant = true;
     418             :           }
     419           0 :           if (DCPS_debug_level > 0) {
     420           0 :             OPENDDS_STRING flag = element.instantiate_per_participant ? "true" : "false";
     421           0 :             ACE_DEBUG((LM_DEBUG,
     422             :                        ACE_TEXT("(%P|%t) TransportRegistry::load_transport_templates(): ")
     423             :                        ACE_TEXT("[%s/%C]: instantiantion rule == %C\n"),
     424             :                        TRANSPORT_TEMPLATE_SECTION_NAME, element.transport_template_name.c_str(), flag.c_str()));
     425           0 :           }
     426           0 :         } else if (name == ACE_TEXT_ALWAYS_CHAR(CUSTOMIZATION_SECTION_NAME)) {
     427           0 :           customization = it->second;
     428           0 :           if (DCPS_debug_level > 0) {
     429           0 :             ACE_DEBUG((LM_DEBUG,
     430             :                        ACE_TEXT("(%P|%t) TransportRegistry::load_transport_templates(): ")
     431             :                        ACE_TEXT("[%s/%C]: customization == %C\n"),
     432             :                        TRANSPORT_TEMPLATE_SECTION_NAME, element.transport_template_name.c_str(), customization.c_str()));
     433             :           }
     434             : 
     435           0 :           ACE_Configuration_Section_Key custom_sect;
     436           0 :           if (cf.open_section(root, CUSTOMIZATION_SECTION_NAME, false, custom_sect) == 0) {
     437           0 :             ValueMap vcm;
     438             : 
     439           0 :             if (pullValues(cf, custom_sect, vcm) > 0) {
     440           0 :               ACE_ERROR_RETURN((LM_ERROR,
     441             :                                 ACE_TEXT("(%P|%t) ERROR: TransportRegistry::load_transport_templates(): ")
     442             :                                 ACE_TEXT("%s sections must have a subsection name\n"),
     443             :                                 CUSTOMIZATION_SECTION_NAME),
     444             :                                 -1);
     445             :             }
     446             : 
     447             :             // Process the subsections of the custom section
     448           0 :             KeyList keys;
     449           0 :             if (processSections(cf, custom_sect, keys) != 0) {
     450           0 :               ACE_ERROR_RETURN((LM_ERROR,
     451             :                                 ACE_TEXT("(%P|%t) TransportRegistry::load_transport_templates(): ")
     452             :                                 ACE_TEXT("too many nesting layers in the [%s] section.\n"),
     453             :                                 CUSTOMIZATION_SECTION_NAME),
     454             :                                 -1);
     455             :               }
     456             : 
     457             :               // add customizations to domain range
     458           0 :               for (KeyList::const_iterator iter = keys.begin(); iter != keys.end(); ++iter) {
     459           0 :                 if (customization == iter->first) {
     460           0 :                   ValueMap values;
     461           0 :                   pullValues(cf, iter->second, values);
     462             : 
     463           0 :                   for (ValueMap::const_iterator it = values.begin(); it != values.end(); ++it) {
     464           0 :                     element.customizations[it->first] = it->second;
     465             :                   }
     466           0 :                 }
     467             :               }
     468           0 :             }
     469           0 :         } else {
     470           0 :           element.transport_info[it->first] = it->second;
     471             :         }
     472           0 :       }
     473             : 
     474           0 :       transport_templates_.push_back(element);
     475           0 :     }
     476           0 :   }
     477             : 
     478           0 :   return 0;
     479           0 : }
     480             : 
     481             : void
     482           0 : TransportRegistry::load_transport_lib(const OPENDDS_STRING& transport_type)
     483             : {
     484           0 :   GuardType guard(lock_);
     485           0 :   if (!load_transport_lib_i(transport_type)) {
     486           0 :     ACE_ERROR((LM_ERROR,
     487             :                ACE_TEXT("(%P|%t) TransportRegistry::load_transport_lib: ")
     488             :                ACE_TEXT("could not load transport_type=%C.\n"),
     489             :                transport_type.c_str()));
     490             :   }
     491           0 : }
     492             : 
     493             : TransportType_rch
     494           0 : TransportRegistry::load_transport_lib_i(const OPENDDS_STRING& transport_type)
     495             : {
     496           0 :   TransportType_rch type;
     497           0 :   if (find(type_map_, transport_type, type) == 0) {
     498           0 :     return type;
     499             :   }
     500             : 
     501             : #if !defined(ACE_AS_STATIC_LIBS)
     502             :   // Attempt to load it.
     503             :   LibDirectiveMap::iterator lib_iter = lib_directive_map_.find(transport_type);
     504             :   if (lib_iter == lib_directive_map_.end()) {
     505             :     ACE_ERROR((LM_ERROR,
     506             :                ACE_TEXT("(%P|%t) TransportRegistry::load_transport_lib_i: ")
     507             :                ACE_TEXT("no directive for transport_type=%C.\n"),
     508             :                transport_type.c_str()));
     509             :     return type;
     510             :   }
     511             : 
     512             :   ACE_TString directive = ACE_TEXT_CHAR_TO_TCHAR(lib_iter->second.c_str());
     513             :   // Release the lock because the transport will call back into the registry.
     514             :   ACE_Reverse_Lock<LockType> rev_lock(lock_);
     515             :   {
     516             :     ACE_Guard<ACE_Reverse_Lock<LockType> > guard(rev_lock);
     517             :     if (0 != ACE_Service_Config::process_directive(directive.c_str())) {
     518             :       return TransportType_rch();
     519             :     }
     520             :   }
     521             : #endif
     522             : 
     523           0 :   find(type_map_, transport_type, type);
     524           0 :   return type;
     525           0 : }
     526             : 
     527             : TransportInst_rch
     528           0 : TransportRegistry::create_inst(const OPENDDS_STRING& name,
     529             :                                const OPENDDS_STRING& transport_type)
     530             : {
     531           0 :   GuardType guard(lock_);
     532             : 
     533           0 :   TransportType_rch type = load_transport_lib_i(transport_type);
     534           0 :   if (!type) {
     535           0 :     ACE_ERROR((LM_ERROR,
     536             :                ACE_TEXT("(%P|%t) TransportRegistry::create_inst: ")
     537             :                ACE_TEXT("transport_type=%C is not registered.\n"),
     538             :                transport_type.c_str()));
     539           0 :     return TransportInst_rch();
     540             :   }
     541             : 
     542           0 :   if (inst_map_.count(name)) {
     543           0 :     ACE_ERROR((LM_ERROR,
     544             :                ACE_TEXT("(%P|%t) TransportRegistry::create_inst: ")
     545             :                ACE_TEXT("name=%C is already in use.\n"),
     546             :                name.c_str()));
     547           0 :     return TransportInst_rch();
     548             :   }
     549           0 :   TransportInst_rch inst (type->new_inst(name));
     550           0 :   inst_map_[name] = inst;
     551           0 :   return inst;
     552           0 : }
     553             : 
     554             : 
     555             : TransportInst_rch
     556           0 : TransportRegistry::get_inst(const OPENDDS_STRING& name) const
     557             : {
     558           0 :   GuardType guard(lock_);
     559           0 :   InstMap::const_iterator found = inst_map_.find(name);
     560           0 :   if (found != inst_map_.end()) {
     561           0 :     return found->second;
     562             :   }
     563           0 :   return TransportInst_rch();
     564           0 : }
     565             : 
     566             : 
     567             : TransportConfig_rch
     568           0 : TransportRegistry::create_config(const OPENDDS_STRING& name)
     569             : {
     570           0 :   GuardType guard(lock_);
     571             : 
     572           0 :   if (config_map_.count(name)) {
     573           0 :     ACE_ERROR((LM_ERROR,
     574             :                ACE_TEXT("(%P|%t) TransportRegistry::create_config: ")
     575             :                ACE_TEXT("name=%C is already in use.\n"),
     576             :                name.c_str()));
     577           0 :     return TransportConfig_rch();
     578             :   }
     579             : 
     580           0 :   TransportConfig_rch inst  (make_rch<TransportConfig>(name));
     581           0 :   config_map_[name] = inst;
     582           0 :   return inst;
     583           0 : }
     584             : 
     585             : 
     586             : TransportConfig_rch
     587           0 : TransportRegistry::get_config(const OPENDDS_STRING& name) const
     588             : {
     589           0 :   GuardType guard(lock_);
     590           0 :   ConfigMap::const_iterator found = config_map_.find(name);
     591           0 :   if (found != config_map_.end()) {
     592           0 :     return found->second;
     593             :   }
     594           0 :   return TransportConfig_rch();
     595           0 : }
     596             : 
     597             : 
     598             : void
     599           0 : TransportRegistry::bind_config(const TransportConfig_rch& cfg,
     600             :                                DDS::Entity_ptr entity)
     601             : {
     602           0 :   if (cfg.is_nil()) {
     603           0 :     throw Transport::NotFound();
     604             :   }
     605           0 :   EntityImpl* ei = dynamic_cast<EntityImpl*>(entity);
     606           0 :   if (!ei) {
     607           0 :     throw Transport::MiscProblem();
     608             :   }
     609             : 
     610           0 :   const DDS::DomainId_t domain_id = ei->get_domain_id();
     611             : 
     612             :   // if domain is in a domain range and config is a transport template,
     613             :   // get the correct config.
     614           0 :   if (TheServiceParticipant->belongs_to_domain_range(domain_id)) {
     615           0 :     bool found = false;
     616           0 :     for (OPENDDS_VECTOR(TransportTemplate)::const_iterator i = transport_templates_.begin(); i != transport_templates_.end(); ++i) {
     617           0 :       if (cfg->name() == i->config_name) {
     618           0 :         found = true;
     619           0 :         break;
     620             :       }
     621             :     }
     622             : 
     623           0 :     if (found)
     624             :     {
     625           0 :       ACE_TString cfg_name = ACE_TEXT_CHAR_TO_TCHAR(cfg->name().c_str());
     626             :       // create if not already created
     627           0 :       int ret = create_transport_template_instance(domain_id, cfg_name);
     628             : 
     629           0 :       if (ret == 0) {
     630             :         // get guid and create unique name for transport instance
     631           0 :         GUID_t guid = ei->get_id();
     632           0 :         if (guid == GUID_UNKNOWN) {
     633           0 :           ACE_ERROR((LM_ERROR,
     634             :                      ACE_TEXT("(%P|%t) TransportRegistry::bind_config: ")
     635             :                      ACE_TEXT("GUID_UNKNOWN. Can not bind entity to a domain template instance.\n")));
     636           0 :           throw Transport::UnableToCreate();
     637             :         }
     638           0 :         OPENDDS_STRING transport_inst_name = GuidConverter(guid).uniqueParticipantId();
     639           0 :         OPENDDS_STRING transport_config_name;
     640             : 
     641           0 :         if (cfg_name.c_str() != 0) {
     642           0 :           transport_config_name = ACE_TEXT_ALWAYS_CHAR(cfg_name.c_str());
     643             :         } else {
     644           0 :           ACE_ERROR((LM_ERROR,
     645             :                      ACE_TEXT("(%P|%t) TransportRegistry::bind_config: ")
     646             :                      ACE_TEXT("Config name is null.\n")));
     647           0 :           throw Transport::UnableToCreate();
     648             :         }
     649             : 
     650           0 :         bool success = create_new_transport_instance_for_participant(domain_id, transport_config_name, transport_inst_name);
     651             : 
     652           0 :         if (success) {
     653             :           // update config
     654           0 :           TransportConfig_rch new_cfg = get_config(transport_config_name);
     655           0 :           update_config_template_instance_info(new_cfg->name(), transport_inst_name);
     656           0 :           ei->transport_config(new_cfg);
     657           0 :           return;
     658           0 :         } else {
     659           0 :           ACE_ERROR((LM_ERROR,
     660             :                      ACE_TEXT("(%P|%t) TransportRegistry::bind_config: ")
     661             :                      ACE_TEXT("Failed to create new transport template instance.\n")));
     662           0 :           throw Transport::UnableToCreate();
     663             :         }
     664           0 :       }
     665           0 :     }
     666             :   }
     667             : 
     668           0 :   ei->transport_config(cfg);
     669             : }
     670             : 
     671             : 
     672             : void
     673           0 : TransportRegistry::remove_transport_template_instance(const OPENDDS_STRING& config_name)
     674             : {
     675           0 :   ConfigTemplateToInstanceMap::iterator i = config_template_to_instance_map_.find(config_name);
     676           0 :   if (i == config_template_to_instance_map_.end()) {
     677           0 :     if (DCPS_debug_level > 4) {
     678           0 :       ACE_DEBUG((LM_DEBUG,
     679             :                ACE_TEXT("(%P|%t) TransportRegistry::remove_transport_template_instance: ")
     680             :                ACE_TEXT("%C is not a transport template instance.\n"),
     681             :                config_name.c_str()));
     682             :     }
     683           0 :     return;
     684             :   }
     685             : 
     686           0 :   const OPENDDS_STRING inst_name = i->second;
     687           0 :   remove_config(config_name);
     688           0 :   remove_inst(inst_name);
     689             : 
     690           0 :   if (DCPS_debug_level > 0) {
     691           0 :     ACE_DEBUG((LM_DEBUG,
     692             :                ACE_TEXT("(%P|%t) DomainParticipantFactoryImpl::delete_participant ")
     693             :                ACE_TEXT("deleted TransportRegistry's dynamically created config %C and instance %C\n"),
     694             :                config_name.c_str(), inst_name.c_str()));
     695             :   }
     696             : 
     697           0 :   config_template_to_instance_map_.erase(i);
     698           0 : }
     699             : 
     700             : 
     701             : TransportConfig_rch
     702           0 : TransportRegistry::fix_empty_default()
     703             : {
     704             :   DBG_ENTRY_LVL("TransportRegistry", "fix_empty_default", 6);
     705           0 :   GuardType guard(lock_);
     706           0 :   if (global_config_.is_nil()
     707           0 :       || !global_config_->instances_.empty()
     708           0 :       || global_config_->name() != DEFAULT_CONFIG_NAME) {
     709           0 :     return global_config_;
     710             :   }
     711           0 :   TransportConfig_rch global_config = global_config_;
     712           0 :   load_transport_lib_i(FALLBACK_TYPE);
     713           0 :   return global_config;
     714           0 : }
     715             : 
     716             : 
     717             : bool
     718           0 : TransportRegistry::register_type(const TransportType_rch& type)
     719             : {
     720             :   DBG_ENTRY_LVL("TransportRegistry", "register_type", 6);
     721           0 :   const OPENDDS_STRING name = type->name();
     722             : 
     723           0 :   GuardType guard(this->lock_);
     724           0 :   if (type_map_.count(name)) {
     725           0 :     return false;
     726             :   }
     727             : 
     728           0 :   type_map_[name] = type;
     729             : 
     730           0 :   if (name == "rtps_udp") {
     731           0 :     type_map_["rtps_discovery"] = type;
     732             :   }
     733             : 
     734           0 :   return true;
     735           0 : }
     736             : 
     737             : bool
     738           0 : TransportRegistry::create_new_transport_instance_for_participant(DDS::DomainId_t id, OPENDDS_STRING& transport_config_name, OPENDDS_STRING& transport_instance_name)
     739             : {
     740             :   // check per_participant
     741           0 :   TransportTemplate templ;
     742           0 :   if (get_transport_template_info(ACE_TEXT_CHAR_TO_TCHAR(transport_config_name.c_str()), templ)) {
     743           0 :     if (!templ.instantiate_per_participant) {
     744           0 :       ACE_ERROR_RETURN((LM_ERROR,
     745             :                         ACE_TEXT("(%P|%t) ERROR: TransportRegistry::")
     746             :                         ACE_TEXT("create_new_transport_instance_for_participant: ")
     747             :                         ACE_TEXT("transport_template missing instantiation_rule=per_participant\n")),
     748             :                       false);
     749             :     }
     750             :   }
     751             : 
     752           0 :   TransportConfig_rch cfg = get_config(transport_config_name);
     753             : 
     754           0 :   OPENDDS_STRING inst_name = cfg->instances_[0]->name() + "_" + to_dds_string(id) + "_" + transport_instance_name;
     755           0 :   OPENDDS_STRING config_name = cfg->name() + "_" + to_dds_string(id) + "_" + transport_instance_name;
     756             : 
     757             :   // assign new config and inst names
     758           0 :   transport_config_name = config_name;
     759           0 :   transport_instance_name = inst_name;
     760             : 
     761           0 :   OpenDDS::DCPS::TransportConfig_rch config = create_config(config_name);
     762           0 :   OpenDDS::DCPS::TransportInst_rch inst = create_inst(inst_name, "rtps_udp");
     763             : 
     764           0 :   ACE_Configuration_Heap ach;
     765           0 :   ACE_Configuration_Section_Key sect_key;
     766             : 
     767           0 :   ach.open();
     768           0 :   ach.open_section(ach.root_section(), ACE_TEXT("the_transport_setup"), true, sect_key);
     769             : 
     770           0 :   if (TheServiceParticipant->belongs_to_domain_range(id) ||
     771           0 :       config_has_transport_template(ACE_TEXT_CHAR_TO_TCHAR(transport_config_name.c_str()))) {
     772           0 :     TransportTemplate tr_inst;
     773             : 
     774           0 :     if (get_transport_template_info(ACE_TEXT_CHAR_TO_TCHAR(cfg->name().c_str()), tr_inst)) {
     775           0 :       ValueMap customs;
     776             : 
     777           0 :       if (!process_customizations(id, tr_inst, customs)) {
     778           0 :         ACE_ERROR_RETURN((LM_ERROR,
     779             :                   ACE_TEXT("(%P|%t) ERROR: TransportRegistry::")
     780             :                   ACE_TEXT("create_new_transport_instance_for_participant ")
     781             :                   ACE_TEXT("could not process_customizations\n")),
     782             :                  false);
     783             :       }
     784             : 
     785             :       // write
     786           0 :       for (ValueMap::const_iterator it = customs.begin(); it != customs.end(); ++it) {
     787           0 :         ach.set_string_value(sect_key, ACE_TEXT_CHAR_TO_TCHAR(it->first.c_str()), ACE_TEXT_CHAR_TO_TCHAR(it->second.c_str()));
     788             :       }
     789           0 :     } else {
     790           0 :       ACE_ERROR_RETURN((LM_ERROR,
     791             :                         ACE_TEXT("(%P|%t) ERROR: TransportRegistry::")
     792             :                         ACE_TEXT("create_new_transport_instance_for_participant ")
     793             :                         ACE_TEXT("could not find transport_template for config %C\n"),
     794             :                         cfg->name().c_str()),
     795             :                        false);
     796             :     }
     797           0 :   } else {
     798           0 :     TransportEntry tr_inst;
     799           0 :     get_transport_info(ACE_TEXT_CHAR_TO_TCHAR(cfg->name().c_str()), tr_inst);
     800             : 
     801           0 :     for (ValueMap::const_iterator it = tr_inst.transport_info.begin();
     802           0 :          it != tr_inst.transport_info.end(); ++it) {
     803           0 :       ach.set_string_value(sect_key, ACE_TEXT_CHAR_TO_TCHAR(it->first.c_str()), ACE_TEXT_CHAR_TO_TCHAR(it->second.c_str()));
     804           0 :       if (DCPS_debug_level > 0) {
     805           0 :         ACE_DEBUG((LM_DEBUG,
     806             :                    ACE_TEXT("(%P|%t) TransportRegistry::")
     807             :                        ACE_TEXT("create_new_transport_entry_for_participant adding %C=%C\n"),
     808             :                    it->first.c_str(), it->second.c_str()));
     809             :       }
     810             :     }
     811           0 :   }
     812             : 
     813           0 :   inst->load(ach, sect_key);
     814           0 :   config->instances_.push_back(inst);
     815             : 
     816           0 :   return true;
     817           0 : }
     818             : 
     819             : void
     820           0 : TransportRegistry::update_config_template_instance_info(const OPENDDS_STRING& config_name, const OPENDDS_STRING& inst_name)
     821             : {
     822           0 :   config_template_to_instance_map_[config_name] = inst_name;
     823           0 : }
     824             : 
     825             : void
     826           9 : TransportRegistry::release()
     827             : {
     828             :   DBG_ENTRY_LVL("TransportRegistry", "release", 6);
     829           9 :   GuardType guard(lock_);
     830           9 :   released_ = true;
     831             : 
     832           9 :   for (InstMap::iterator iter = inst_map_.begin(); iter != inst_map_.end(); ++iter) {
     833           0 :     iter->second->shutdown();
     834             :   }
     835             : 
     836           9 :   config_template_to_instance_map_.clear();
     837           9 :   transport_templates_.clear();
     838           9 :   transports_.clear();
     839           9 :   type_map_.clear();
     840           9 :   inst_map_.clear();
     841           9 :   config_map_.clear();
     842           9 :   domain_default_config_map_.clear();
     843           9 :   global_config_.reset();
     844           9 : }
     845             : 
     846             : bool
     847           0 : TransportRegistry::released() const
     848             : {
     849           0 :   GuardType guard(lock_);
     850           0 :   return released_;
     851           0 : }
     852             : 
     853             : OPENDDS_STRING
     854           0 : TransportRegistry::get_transport_template_instance_name(const DDS::DomainId_t id)
     855             : {
     856           0 :   OpenDDS::DCPS::Discovery::RepoKey configured_name = "transport_template_instance_";
     857           0 :   configured_name += to_dds_string(id);
     858           0 :   return configured_name;
     859           0 : }
     860             : 
     861             : OPENDDS_STRING
     862           0 : TransportRegistry::get_config_instance_name(const DDS::DomainId_t id)
     863             : {
     864           0 :   OpenDDS::DCPS::Discovery::RepoKey configured_name = "templ_config_";
     865           0 :   configured_name += to_dds_string(id);
     866           0 :   return configured_name;
     867           0 : }
     868             : 
     869             : int
     870           0 : TransportRegistry::create_transport_template_instance(DDS::DomainId_t domain, const ACE_TString& config_name)
     871             : {
     872           0 :   OPENDDS_STRING transport_inst_name = get_transport_template_instance_name(domain);
     873           0 :   OPENDDS_STRING config_inst_name = get_config_instance_name(domain);
     874             : 
     875             :   // has it already been created?
     876           0 :   ConfigMap::const_iterator i = config_map_.find(config_inst_name);
     877           0 :   if (i != config_map_.end()) {
     878           0 :     return 0; // already created
     879             :   }
     880             : 
     881           0 :   if (has_transport_templates()) {
     882           0 :     TransportTemplate tr_inst;
     883             : 
     884           0 :     if (get_transport_template_info(config_name, tr_inst)) {
     885           0 :       ACE_Configuration_Heap tcf;
     886           0 :       tcf.open();
     887           0 :       const ACE_Configuration_Section_Key& root = tcf.root_section();
     888             : 
     889             :       // create config
     890           0 :       ACE_Configuration_Section_Key csect;
     891           0 :       tcf.open_section(root, ACE_TEXT("config"), true /* create */, csect);
     892           0 :       ACE_Configuration_Section_Key csub_sect;
     893           0 :       tcf.open_section(csect, ACE_TEXT_CHAR_TO_TCHAR(config_inst_name.c_str()), true /* create */, csub_sect);
     894           0 :       tcf.set_string_value(csub_sect, ACE_TEXT("transports"), ACE_TEXT_CHAR_TO_TCHAR(transport_inst_name.c_str()));
     895             : 
     896             :       // create matching transport section
     897           0 :       ACE_Configuration_Section_Key tsect;
     898           0 :       tcf.open_section(root, ACE_TEXT("transport"), true /* create */, tsect);
     899           0 :       ACE_Configuration_Section_Key tsub_sect;
     900           0 :       tcf.open_section(tsect, ACE_TEXT_CHAR_TO_TCHAR(transport_inst_name.c_str()), true /* create */, tsub_sect);
     901             : 
     902           0 :       ValueMap customs;
     903             : 
     904           0 :       if (!process_customizations(domain, tr_inst, customs)) {
     905           0 :         ACE_ERROR_RETURN((LM_ERROR,
     906             :                           ACE_TEXT("(%P|%t) ERROR: TransportRegistry::")
     907             :                           ACE_TEXT("create_transport_template_instance ")
     908             :                           ACE_TEXT("could not process_customizations\n")),
     909             :                          false);
     910             :       }
     911             : 
     912             :       // write
     913           0 :       for (ValueMap::const_iterator it = customs.begin(); it != customs.end(); ++it) {
     914           0 :         tcf.set_string_value(tsub_sect, ACE_TEXT_CHAR_TO_TCHAR(it->first.c_str()), ACE_TEXT_CHAR_TO_TCHAR(it->second.c_str()));
     915             : 
     916           0 :         if (DCPS_debug_level > 0) {
     917           0 :           ACE_DEBUG((LM_DEBUG,
     918             :                      ACE_TEXT("(%P|%t) TransportRegistry::")
     919             :                      ACE_TEXT("create_transport_template_instance adding %C=%C\n"),
     920             :                      it->first.c_str(), it->second.c_str()));
     921             :         }
     922             :       }
     923             : 
     924             :       // load transport
     925           0 :       int status = this->load_transport_configuration("transport_config_" + to_dds_string(domain), tcf);
     926             : 
     927           0 :       if (status != 0) {
     928           0 :         ACE_ERROR_RETURN((LM_ERROR,
     929             :                           ACE_TEXT("(%P|%t) ERROR: TransportRegistry::create_transport_template_instance ")
     930             :                           ACE_TEXT("load_transport_configuration() returned %d\n"),
     931             :                           status),
     932             :                         -1);
     933             :       }
     934             : 
     935           0 :     }
     936             : 
     937           0 :   }
     938             : 
     939           0 :   return 0;
     940           0 : }
     941             : 
     942             : bool
     943           0 : TransportRegistry::config_has_transport_template(const ACE_TString& config_name) const
     944             : {
     945           0 :   for (OPENDDS_VECTOR(TransportTemplate)::const_iterator i = transport_templates_.begin(); i != transport_templates_.end(); ++i) {
     946           0 :     if (!ACE_OS::strcmp(ACE_TEXT_ALWAYS_CHAR(config_name.c_str()), i->config_name.c_str())) {
     947           0 :       return true;
     948             :     }
     949             :   }
     950             : 
     951           0 :   return false;
     952             : }
     953             : 
     954             : bool
     955           0 : TransportRegistry::get_transport_template_info(const ACE_TString& config_name, TransportTemplate& inst)
     956             : {
     957           0 :   bool ret = false;
     958           0 :   if (has_transport_templates()) {
     959           0 :     for (OPENDDS_VECTOR(TransportTemplate)::const_iterator i = transport_templates_.begin(); i != transport_templates_.end(); ++i) {
     960           0 :       if (!ACE_OS::strcmp(ACE_TEXT_ALWAYS_CHAR(config_name.c_str()), i->config_name.c_str())) {
     961           0 :         inst.transport_template_name = i->transport_template_name;
     962           0 :         inst.config_name = i->config_name;
     963           0 :         inst.instantiate_per_participant = i->instantiate_per_participant;
     964           0 :         inst.customizations = i->customizations;
     965           0 :         inst.transport_info = i->transport_info;
     966             : 
     967           0 :         ret = true;
     968           0 :         break;
     969             :       }
     970             :     }
     971             :   }
     972             : 
     973           0 :   if (DCPS_debug_level > 0) {
     974           0 :     ACE_DEBUG((LM_DEBUG,
     975             :                ACE_TEXT("(%P|%t) TransportRegistry::get_transport_template_info: ")
     976             :                ACE_TEXT("%C config %s\n"),
     977             :                ret ? "found" : "did not find", config_name.c_str()));
     978             :   }
     979             : 
     980           0 :   return ret;
     981             : }
     982             : 
     983           0 : bool TransportRegistry::process_customizations(const DDS::DomainId_t id, const TransportTemplate& tr_inst, ValueMap& customs)
     984             : {
     985           0 :   for (ValueMap::const_iterator it = tr_inst.transport_info.begin();
     986           0 :        it != tr_inst.transport_info.end(); ++it) {
     987             :     // customization.
     988           0 :     ValueMap::const_iterator idx = tr_inst.customizations.find(it->first);
     989           0 :     if (idx != tr_inst.customizations.end()) {
     990           0 :       OPENDDS_STRING addr = it->second;
     991           0 :       OPENDDS_STRING custom = idx->second;
     992             : 
     993             :       // check for 'add_domain_id_to_ip_addr' and 'add_domain_id_to_port'
     994           0 :       bool add_to_ip = false;
     995           0 :       bool add_to_port = false;
     996             : 
     997           0 :       OPENDDS_STRING val1;
     998           0 :       OPENDDS_STRING val2;
     999             : 
    1000           0 :       size_t comma_pos = custom.find(',');
    1001           0 :       if (comma_pos != OPENDDS_STRING::npos) {
    1002           0 :         val1 = custom.substr(0, comma_pos);
    1003             :         // remove spaces
    1004           0 :         val1.erase(std::remove(val1.begin(), val1.end(), ' '), val1.end());
    1005             : 
    1006           0 :         val2 = custom.substr(comma_pos + 1);
    1007           0 :         val2.erase(std::remove(val2.begin(), val2.end(), ' '), val2.end());
    1008             : 
    1009           0 :         add_to_ip = (val1 == CUSTOM_ADD_DOMAIN_TO_IP || val2 == CUSTOM_ADD_DOMAIN_TO_IP);
    1010           0 :         add_to_port = (val1 == CUSTOM_ADD_DOMAIN_TO_PORT || val2 == CUSTOM_ADD_DOMAIN_TO_PORT);
    1011             : 
    1012             :       } else {
    1013           0 :         custom.erase(std::remove(custom.begin(), custom.end(), ' '), custom.end());
    1014             : 
    1015           0 :         add_to_ip = (custom == CUSTOM_ADD_DOMAIN_TO_IP);
    1016           0 :         add_to_port = (custom == CUSTOM_ADD_DOMAIN_TO_PORT);
    1017             :       }
    1018             : 
    1019           0 :       if (!add_to_ip && !add_to_port) {
    1020           0 :         ACE_ERROR_RETURN((LM_ERROR,
    1021             :                           ACE_TEXT("(%P|%t) TransportRegistry::process_customizations: ")
    1022             :                           ACE_TEXT("%C customization is not supported. Supported values are %C and %C\n"),
    1023             :                           custom.c_str(), CUSTOM_ADD_DOMAIN_TO_IP.c_str(), CUSTOM_ADD_DOMAIN_TO_PORT.c_str()),
    1024             :                          false);
    1025             :       }
    1026             : 
    1027             :       // only add_domain_id_to_ip_addr and add_domain_id_to_port are supported at this time.
    1028           0 :       if (add_to_ip) {
    1029           0 :         size_t pos = addr.find_last_of(".");
    1030           0 :         if (pos != OPENDDS_STRING::npos) {
    1031           0 :           OPENDDS_STRING custom = addr.substr(pos + 1);
    1032             : 
    1033           0 :           OPENDDS_STRING port = "";
    1034           0 :           OPENDDS_STRING last_octet = "";
    1035             : 
    1036           0 :           size_t cpos = custom.find(":");
    1037           0 :           if (cpos != OPENDDS_STRING::npos) {
    1038           0 :             port = custom.substr(cpos);
    1039           0 :             last_octet = custom.substr(0, cpos);
    1040             :           } else {
    1041           0 :             last_octet = custom;
    1042             :           }
    1043           0 :           int val = 0;
    1044             : 
    1045           0 :           if (!convertToInteger(last_octet, val)) {
    1046           0 :             ACE_ERROR_RETURN((LM_ERROR,
    1047             :                               ACE_TEXT("(%P|%t) ERROR: TransportRegistry::")
    1048             :                               ACE_TEXT("process_customizations ")
    1049             :                               ACE_TEXT("could not convert %C to integer\n"),
    1050             :                               custom.c_str()),
    1051             :                              false);
    1052             :           }
    1053             : 
    1054           0 :           val += id;
    1055           0 :           addr = addr.substr(0, pos);
    1056           0 :           addr += "." + to_dds_string(val);
    1057           0 :           if (port != "") {
    1058           0 :             addr += port;
    1059             :           }
    1060           0 :         } else {
    1061           0 :           ACE_ERROR_RETURN((LM_ERROR,
    1062             :                             ACE_TEXT("(%P|%t) ERROR: Service_Participant::")
    1063             :                             ACE_TEXT("process_customizations ")
    1064             :                             ACE_TEXT("could not add_domain_id_to_ip_addr for address %C\n"),
    1065             :                             idx->second.c_str()),
    1066             :                            false);
    1067             :         }
    1068             : 
    1069           0 :         if (DCPS_debug_level > 0) {
    1070           0 :           ACE_DEBUG((LM_DEBUG,
    1071             :                      ACE_TEXT("(%P|%t) TransportRegistry::")
    1072             :                      ACE_TEXT("process_customizations processing add_domain_id_to_ip_addr: %C=%C\n"),
    1073             :                      it->first.c_str(), addr.c_str()));
    1074             :         }
    1075             :       }
    1076             : 
    1077           0 :       if (add_to_port) {
    1078           0 :         size_t pos = addr.find_last_of(":");
    1079           0 :         if (pos == OPENDDS_STRING::npos) {
    1080             :           // use default port + domainId. See 9.6.1.3 in the RTPS 2.2 protocol specification.
    1081           0 :           const int PB = 7400;
    1082           0 :           const int DG = 250;
    1083           0 :           const int D2 = 1;
    1084           0 :           int rtpsPort = PB + DG * id + D2;
    1085           0 :           rtpsPort += id;
    1086           0 :           addr += ":" + to_dds_string(rtpsPort);
    1087             :         } else {
    1088             :           // address has a port supplied
    1089           0 :           int rtpsPort = -1;
    1090           0 :           if (convertToInteger(addr.substr(pos + 1), rtpsPort)) {
    1091           0 :             addr = addr.substr(0, pos);
    1092           0 :             rtpsPort += id;
    1093           0 :             addr += ":" + to_dds_string(rtpsPort);
    1094             :           } else {
    1095           0 :             ACE_ERROR_RETURN((LM_ERROR,
    1096             :                               ACE_TEXT("(%P|%t) ERROR: Service_Participant::")
    1097             :                               ACE_TEXT("process_customizations ")
    1098             :                               ACE_TEXT("could not add_domain_id_to_port for %C.\n"),
    1099             :                               idx->second.c_str()),
    1100             :                              false);
    1101             :           }
    1102             : 
    1103           0 :           if (DCPS_debug_level > 0) {
    1104           0 :             ACE_DEBUG((LM_DEBUG,
    1105             :                      ACE_TEXT("(%P|%t) TransportRegistry::")
    1106             :                      ACE_TEXT("process_customizations processing add_domain_id_to_port: %C ==> %C\n"),
    1107             :                      it->first.c_str(), addr.c_str()));
    1108             :           }
    1109             : 
    1110             :         }
    1111             : 
    1112           0 :         if (DCPS_debug_level > 0) {
    1113           0 :           ACE_DEBUG((LM_DEBUG,
    1114             :                      ACE_TEXT("(%P|%t) TransportRegistry::")
    1115             :                      ACE_TEXT("process_customizations processing add_domain_id_to_port: %C=%C\n"),
    1116             :                      it->first.c_str(), addr.c_str()));
    1117             :         }
    1118             :       }
    1119             : 
    1120           0 :       customs[idx->first] = addr.c_str();
    1121           0 :     } else {
    1122           0 :       customs[it->first] = it->second.c_str();
    1123           0 :       if (DCPS_debug_level > 0) {
    1124           0 :         ACE_DEBUG((LM_DEBUG,
    1125             :                    ACE_TEXT("(%P|%t) TransportRegistry::")
    1126             :                    ACE_TEXT("process_customizations adding %C=%C\n"),
    1127             :                    it->first.c_str(), it->second.c_str()));
    1128             :       }
    1129             :     }
    1130             :   }
    1131             : 
    1132           0 :   return true;
    1133             : }
    1134             : 
    1135           0 : bool TransportRegistry::has_transport_templates() const
    1136             : {
    1137           0 :   return !transport_templates_.empty();
    1138             : }
    1139             : 
    1140             : bool
    1141           0 : TransportRegistry::get_transport_info(const ACE_TString& config_name, TransportEntry& inst)
    1142             : {
    1143           0 :   bool ret = false;
    1144           0 :   if (has_transports()) {
    1145           0 :     for (OPENDDS_VECTOR(TransportEntry)::const_iterator i = transports_.begin(); i != transports_.end(); ++i) {
    1146           0 :       if (!ACE_OS::strcmp(ACE_TEXT_ALWAYS_CHAR(config_name.c_str()), ACE_TEXT_ALWAYS_CHAR(i->config_name.c_str()))) {
    1147           0 :         inst.transport_name = i->transport_name;
    1148           0 :         inst.config_name = i->config_name;
    1149           0 :         inst.transport_info = i->transport_info;
    1150             : 
    1151           0 :         ret = true;
    1152           0 :         break;
    1153             :       }
    1154             :     }
    1155             :   }
    1156             : 
    1157           0 :   if (DCPS_debug_level > 0) {
    1158           0 :     ACE_DEBUG((LM_DEBUG,
    1159             :                ACE_TEXT("(%P|%t) TransportRegistry::get_transport_info: ")
    1160             :                ACE_TEXT("%C config %s\n"),
    1161             :                ret ? "found" : "did not find", config_name.c_str()));
    1162             :   }
    1163             : 
    1164           0 :   return ret;
    1165             : }
    1166             : 
    1167           0 : bool TransportRegistry::has_transports() const
    1168             : {
    1169           0 :   return !transports_.empty();
    1170             : }
    1171             : 
    1172             : }
    1173             : }
    1174             : 
    1175             : OPENDDS_END_VERSIONED_NAMESPACE_DECL

Generated by: LCOV version 1.16