MulticastTransport::MulticastTransport(const TransportInst_rch& inst) : config_i_(0) { if (!inst.is_nil()) { configure(inst.in()); } }
RtpsUdpTransport::RtpsUdpTransport(const TransportInst_rch& inst) : default_listener_(0) { if (!inst.is_nil()) { if (!configure(inst.in())) { throw Transport::UnableToCreate(); } } }
ShmemTransport::ShmemTransport(const TransportInst_rch& inst) : alloc_(0) , read_task_(0) , hostname_(get_fully_qualified_hostname()) { if (!inst.is_nil()) { if (!configure(inst.in())) { throw Transport::UnableToCreate(); } } }
TcpTransport::TcpTransport(const TransportInst_rch& inst) : acceptor_(new TcpAcceptor(this)), con_checker_(new TcpConnectionReplaceTask(this)) { DBG_ENTRY_LVL("TcpTransport","TcpTransport",6); if (!inst.is_nil()) { if (!configure(inst.in())) { delete con_checker_; delete acceptor_; throw Transport::UnableToCreate(); } } }
void TransportConfig::sorted_insert(const TransportInst_rch& inst) { const OPENDDS_STRING name = inst->name(); InstancesType::iterator it = instances_.begin(); while (it != instances_.end() && (*it)->name() < name) { ++it; } instances_.insert(it, inst); }
int TransportRegistry::load_transport_configuration(const OPENDDS_STRING& file_name, ACE_Configuration_Heap& cf) { const ACE_Configuration_Section_Key &root = cf.root_section(); // Create a vector to hold configuration information so we can populate // them after the transports instances are created. typedef std::pair<TransportConfig_rch, OPENDDS_VECTOR(OPENDDS_STRING) > ConfigInfo; OPENDDS_VECTOR(ConfigInfo) configInfoVec; // Record the transport instances created, so we can place them // in the implicit transport configuration for this file. OPENDDS_LIST(TransportInst_rch) instances; ACE_TString sect_name; for (int index = 0; cf.enumerate_sections(root, index, sect_name) == 0; ++index) { if (ACE_OS::strcmp(sect_name.c_str(), TRANSPORT_SECTION_NAME) == 0) { // found the [transport/*] section, now iterate through subsections... ACE_Configuration_Section_Key sect; if (cf.open_section(root, sect_name.c_str(), 0, sect) != 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("failed to open section %s\n"), sect_name.c_str()), -1); } else { // Ensure there are no properties in this section ValueMap vm; if (pullValues(cf, sect, vm) > 0) { // There are values inside [transport] ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("transport sections must have a section name\n"), sect_name.c_str()), -1); } // Process the subsections of this section (the individual transport // impls). KeyList keys; if (processSections( cf, sect, keys ) != 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("too many nesting layers in [%s] section.\n"), sect_name.c_str()), -1); } for (KeyList::const_iterator it=keys.begin(); it != keys.end(); ++it) { OPENDDS_STRING transport_id = (*it).first; ACE_Configuration_Section_Key inst_sect = (*it).second; ValueMap values; if (pullValues( cf, (*it).second, values ) != 0) { // Get the factory_id for the transport. OPENDDS_STRING transport_type; ValueMap::const_iterator vm_it = values.find("transport_type"); if (vm_it != values.end()) { transport_type = (*vm_it).second; } else { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("missing transport_type in [transport/%C] section.\n"), transport_id.c_str()), -1); } // Create the TransportInst object and load the transport // configuration in ACE_Configuration_Heap to the TransportInst // object. TransportInst_rch inst = this->create_inst(transport_id, transport_type); if (inst == 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("Unable to create transport instance in [transport/%C] section.\n"), transport_id.c_str()), -1); } instances.push_back(inst); inst->load(cf, inst_sect); } else { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("missing transport_type in [transport/%C] section.\n"), transport_id.c_str()), -1); } } } } else if (ACE_OS::strcmp(sect_name.c_str(), CONFIG_SECTION_NAME) == 0) { // found the [config/*] section, now iterate through subsections... ACE_Configuration_Section_Key sect; if (cf.open_section(root, sect_name.c_str(), 0, sect) != 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("failed to open section [%s]\n"), sect_name.c_str()), -1); } else { // Ensure there are no properties in this section ValueMap vm; if (pullValues(cf, sect, vm) > 0) { // There are values inside [config] ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("config sections must have a section name\n"), sect_name.c_str()), -1); } // Process the subsections of this section (the individual config // impls). KeyList keys; if (processSections( cf, sect, keys ) != 0) { // Don't allow multiple layers of nesting ([config/x/y]). ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("too many nesting layers in [%s] section.\n"), sect_name.c_str()), -1); } for (KeyList::const_iterator it=keys.begin(); it != keys.end(); ++it) { OPENDDS_STRING config_id = (*it).first; // Create a TransportConfig object. TransportConfig_rch config = this->create_config(config_id); if (config == 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("Unable to create transport config in [config/%C] section.\n"), config_id.c_str()), -1); } ValueMap values; pullValues( cf, (*it).second, values ); ConfigInfo configInfo; configInfo.first = config; for (ValueMap::const_iterator it=values.begin(); it != values.end(); ++it) { OPENDDS_STRING name = (*it).first; if (name == "transports") { OPENDDS_STRING value = (*it).second; char delim = ','; size_t pos = 0; OPENDDS_STRING token; while ((pos = value.find(delim)) != OPENDDS_STRING::npos) { token = value.substr(0, pos); configInfo.second.push_back(token); value.erase(0, pos + 1); } configInfo.second.push_back(value); configInfoVec.push_back(configInfo); } else if (name == "swap_bytes") { OPENDDS_STRING value = (*it).second; if ((value == "1") || (value == "true")) { config->swap_bytes_ = true; } else if ((value != "0") && (value != "false")) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("Illegal value for swap_bytes (%C) in [config/%C] section.\n"), value.c_str(), config_id.c_str()), -1); } } else if (name == "passive_connect_duration") { OPENDDS_STRING value = (*it).second; if (!convertToInteger(value, config->passive_connect_duration_)) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("Illegal integer value for passive_connect_duration (%s) in [config/%C] section.\n"), value.c_str(), config_id.c_str()), -1); } } else { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("Unexpected entry (%C) in [config/%C] section.\n"), name.c_str(), config_id.c_str()), -1); } } if (configInfo.second.size() == 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("No transport instances listed in [config/%C] section.\n"), config_id.c_str()), -1); } } } } else if (ACE_OS::strncmp(sect_name.c_str(), OLD_TRANSPORT_PREFIX.c_str(), OLD_TRANSPORT_PREFIX.length()) == 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: ") ACE_TEXT("Obsolete transport configuration found (%s).\n"), sect_name.c_str()), -1); } } // Populate the configurations with instances for (unsigned int i = 0; i < configInfoVec.size(); ++i) { TransportConfig_rch config = configInfoVec[i].first; OPENDDS_VECTOR(OPENDDS_STRING)& insts = configInfoVec[i].second; for (unsigned int j = 0; j < insts.size(); ++j) { TransportInst_rch inst = this->get_inst(insts[j]); if (inst == 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("The inst (%C) in [config/%C] section is undefined.\n"), insts[j].c_str(), config->name().c_str()), -1); } config->instances_.push_back(inst); } } // Create and populate the default configuration for this // file with all the instances from this file. if (!instances.empty()) { TransportConfig_rch config = this->create_config(file_name); if (config == 0) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%P|%t) TransportRegistry::load_transport_configuration: ") ACE_TEXT("Unable to create default transport config.\n"), file_name.c_str()), -1); } instances.sort(predicate); for (OPENDDS_LIST(TransportInst_rch)::const_iterator it = instances.begin(); it != instances.end(); ++it) { config->instances_.push_back(*it); } } return 0; }
int DDS_TEST::test(ACE_TString host, u_short port) { if (host.empty() || port == 0) { std::cerr << "ERROR: -h <host> and -p <port> options are required\n"; return 1; } // 0. initialization ACE_INET_Addr remote_addr(port, host.c_str()); TransportInst_rch inst = TheTransportRegistry->create_inst("my_rtps", "rtps_udp"); RtpsUdpInst* rtps_inst = dynamic_cast<RtpsUdpInst*>(inst.in()); if (!rtps_inst) { std::cerr << "ERROR: Failed to cast to RtpsUdpInst\n"; return 1; } rtps_inst->datalink_release_delay_ = 0; rtps_inst->heartbeat_period_ = ACE_Time_Value(0, 100*1000 /*microseconds*/); TransportConfig_rch cfg = TheTransportRegistry->create_config("cfg"); cfg->instances_.push_back(inst); TheTransportRegistry->global_config(cfg); RepoIdBuilder local; local.federationId(0x01234567); // guidPrefix1 local.participantId(0x89abcdef); // guidPrefix2 local.entityKey(0x012345); local.entityKind(ENTITYKIND_USER_WRITER_WITH_KEY); OpenDDS::RTPS::GUID_t local_guid(local); const OpenDDS::RTPS::GuidPrefix_t& local_prefix = local_guid.guidPrefix; RepoIdBuilder remote; // these values must match what's in subscriber.cpp remote.federationId(0x01234567); // guidPrefix1 remote.participantId(0xefcdab89); // guidPrefix2 remote.entityKey(0x452310); remote.entityKind(ENTITYKIND_USER_READER_WITH_KEY); LocatorSeq locators; locators.length(1); locators[0].kind = (remote_addr.get_type() == AF_INET6) ? LOCATOR_KIND_UDPv6 : LOCATOR_KIND_UDPv4; locators[0].port = port; address_to_bytes(locators[0].address, remote_addr); size_t size_locator = 0, padding_locator = 0; gen_find_size(locators, size_locator, padding_locator); ACE_Message_Block mb_locator(size_locator + padding_locator + 1); Serializer ser_loc(&mb_locator, ACE_CDR_BYTE_ORDER, Serializer::ALIGN_CDR); ser_loc << locators; ser_loc << ACE_OutputCDR::from_boolean(false); // requires inline QoS SimpleDataWriter sdw(local_guid); sdw.enable_transport(true /*reliable*/, false /*durable*/); AssociationData subscription; subscription.remote_id_ = remote; subscription.remote_reliable_ = false; subscription.remote_data_.length(1); subscription.remote_data_[0].transport_type = "rtps_udp"; subscription.remote_data_[0].data.replace( static_cast<CORBA::ULong>(mb_locator.length()), &mb_locator); if (!sdw.init(subscription)) { std::cerr << "publisher TransportClient::associate() failed\n"; return 1; } // 1. send by directly writing an RTPS Message to the socket const Header hdr = { {'R', 'T', 'P', 'S'}, PROTOCOLVERSION, VENDORID_OPENDDS, {local_prefix[0], local_prefix[1], local_prefix[2], local_prefix[3], local_prefix[4], local_prefix[5], local_prefix[6], local_prefix[7], local_prefix[8], local_prefix[9], local_prefix[10], local_prefix[11]} }; const ACE_Time_Value now = ACE_OS::gettimeofday(); log_time(now); const double conv = 4294.967296; // NTP fractional (2^-32) sec per microsec const InfoTimestampSubmessage it = { {INFO_TS, 1, 8}, {static_cast<ACE_CDR::Long>(now.sec()), static_cast<ACE_CDR::ULong>(now.usec() * conv)} }; DataSubmessage ds = { {DATA, 7, 20 + 24 + 12 + sizeof(text)}, 0, 16, ENTITYID_UNKNOWN, local_guid.entityId, {0, 1}, ParameterList() }; TestMsg data; data.key = 0x09230923; data.value = text; ds.inlineQos.length(1); OpenDDS::RTPS::KeyHash_t hash; marshal_key_hash(data, hash); ds.inlineQos[0].key_hash(hash); const ACE_CDR::ULong encap = 0x00000100; // {CDR_LE, options} in BE format size_t size = 0, padding = 0; gen_find_size(hdr, size, padding); gen_find_size(it, size, padding); gen_find_size(ds, size, padding); find_size_ulong(size, padding); gen_find_size(data, size, padding); ACE_Message_Block msg(size + padding); Serializer ser(&msg, host_is_bigendian, Serializer::ALIGN_CDR); bool ok = (ser << hdr) && (ser << it) && (ser << ds) && (ser << encap) && (ser << data); if (!ok) { std::cerr << "ERROR: failed to serialize RTPS message\n"; return 1; } ACE_INET_Addr local_addr; ACE_SOCK_Dgram sock(local_addr); ssize_t res = sock.send(msg.rd_ptr(), msg.length(), remote_addr); if (res < 0) { std::cerr << "ERROR: error in send()\n"; return 1; } else { std::ostringstream oss; oss << "Sent " << res << " bytes.\n"; ACE_DEBUG((LM_INFO, oss.str().c_str())); } // 2a. send control messages through the OpenDDS transport // Send an instance registration { TestMsg control_sample; control_sample.key = 0x04030201; DataSampleHeader dsh; dsh.message_id_ = INSTANCE_REGISTRATION; dsh.sequence_ = SequenceNumber::SEQUENCENUMBER_UNKNOWN(); dsh.publication_id_ = local_guid; dsh.key_fields_only_ = true; // Calculate the data buffer length size = 0; padding = 0; OpenDDS::DCPS::KeyOnly<const TestMsg> ko_instance_data(control_sample); find_size_ulong(size, padding); // encap gen_find_size(ko_instance_data, size, padding); dsh.message_length_ = static_cast<ACE_UINT32>(size + padding); ACE_Message_Block* ir_mb = new ACE_Message_Block(DataSampleHeader::max_marshaled_size(), ACE_Message_Block::MB_DATA, new ACE_Message_Block(dsh.message_length_)); *ir_mb << dsh; OpenDDS::DCPS::Serializer serializer(ir_mb->cont(), host_is_bigendian, Serializer::ALIGN_CDR); ok = (serializer << encap) && (serializer << ko_instance_data); if (!ok) { std::cerr << "ERROR: failed to serialize data for instance registration\n"; return 1; } ::DDS_TEST::force_inline_qos(false); // No inline QoS sdw.send_control(dsh, ir_mb); // Send a dispose instance { dsh.message_id_ = DISPOSE_INSTANCE; ACE_Message_Block* di_mb = new ACE_Message_Block(DataSampleHeader::max_marshaled_size(), ACE_Message_Block::MB_DATA, new ACE_Message_Block(dsh.message_length_)); *di_mb << dsh; OpenDDS::DCPS::Serializer serializer(di_mb->cont(), host_is_bigendian, Serializer::ALIGN_CDR); ok = (serializer << encap) && (serializer << ko_instance_data); if (!ok) { std::cerr << "ERROR: failed to serialize data for dispose instance\n"; return 1; } ::DDS_TEST::force_inline_qos(true); // Inline QoS sdw.inline_qos_mode_ = SimpleDataWriter::PARTIAL_MOD_QOS; sdw.send_control(dsh, di_mb); } // Send an unregister instance { dsh.message_id_ = UNREGISTER_INSTANCE; ACE_Message_Block* ui_mb = new ACE_Message_Block(DataSampleHeader::max_marshaled_size(), ACE_Message_Block::MB_DATA, new ACE_Message_Block(dsh.message_length_)); *ui_mb << dsh; OpenDDS::DCPS::Serializer serializer(ui_mb->cont(), host_is_bigendian, Serializer::ALIGN_CDR); ok = (serializer << encap) && (serializer << ko_instance_data); if (!ok) { std::cerr << "ERROR: failed to serialize data for unregister instance\n"; return 1; } ::DDS_TEST::force_inline_qos(true); // Inline QoS sdw.inline_qos_mode_ = SimpleDataWriter::FULL_MOD_QOS; sdw.send_control(dsh, ui_mb); } // Send a dispose & unregister instance { dsh.message_id_ = DISPOSE_UNREGISTER_INSTANCE; ACE_Message_Block* ui_mb = new ACE_Message_Block(DataSampleHeader::max_marshaled_size(), ACE_Message_Block::MB_DATA, new ACE_Message_Block(dsh.message_length_)); *ui_mb << dsh; OpenDDS::DCPS::Serializer serializer(ui_mb->cont(), host_is_bigendian, Serializer::ALIGN_CDR); ok = (serializer << encap) && (serializer << ko_instance_data); if (!ok) { std::cerr << "ERROR: failed to serialize data for dispose unregister instance\n"; return 1; } ::DDS_TEST::force_inline_qos(true); // Inline QoS sdw.inline_qos_mode_ = SimpleDataWriter::FULL_MOD_QOS; sdw.send_control(dsh, ui_mb); } } // 2b. send sample data through the OpenDDS transport TransportSendElementAllocator alloc(2, sizeof(TransportSendElementAllocator)); DataSampleElement elements[] = { DataSampleElement(local_guid, &sdw, 0, &alloc, 0), // Data Sample DataSampleElement(local_guid, &sdw, 0, &alloc, 0), // Data Sample (key=99 means end) }; SendStateDataSampleList list; list.head_ = elements; list.size_ = sizeof(elements) / sizeof(elements[0]); list.tail_ = &elements[list.size() - 1]; for (int i = 0; i < list.size() - 1; ++i) { DDS_TEST::set_next_send_sample(elements[i], &elements[i + 1]); } // Send a regular data sample int index = 0; DataSampleHeader& dsh = elements[index].header_; dsh.message_id_ = SAMPLE_DATA; dsh.publication_id_ = local_guid; dsh.sequence_ = 3; // test GAP generation const ACE_Time_Value tv = ACE_OS::gettimeofday(); log_time(tv); DDS::Time_t st = time_value_to_time(tv); dsh.source_timestamp_sec_ = st.sec; dsh.source_timestamp_nanosec_ = st.nanosec; // Calculate the data buffer length size = 0; padding = 0; find_size_ulong(size, padding); // encap gen_find_size(data, size, padding); dsh.message_length_ = static_cast<ACE_UINT32>(size + padding); elements[index].sample_ = new ACE_Message_Block(DataSampleHeader::max_marshaled_size(), ACE_Message_Block::MB_DATA, new ACE_Message_Block(dsh.message_length_)); *elements[index].sample_ << dsh; Serializer ser2(elements[index].sample_->cont(), host_is_bigendian, Serializer::ALIGN_CDR); ok = (ser2 << encap) && (ser2 << data); if (!ok) { std::cerr << "ERROR: failed to serialize data for elements[" << index << "]\n"; return 1; } // Send a data sample with a key of 99 to terminate the subscriber index++; DataSampleHeader& dsh2 = elements[index].header_; dsh2.sequence_ = dsh.sequence_+1; dsh2.message_id_ = SAMPLE_DATA; dsh.publication_id_ = local_guid; dsh2.key_fields_only_ = false; const ACE_Time_Value tv2 = ACE_OS::gettimeofday(); log_time(tv2); DDS::Time_t st2 = time_value_to_time(tv2); dsh2.source_timestamp_sec_ = st2.sec; dsh2.source_timestamp_nanosec_ = st2.nanosec; data.key = 99; data.value = ""; // Calculate the data buffer length size = 0; padding = 0; find_size_ulong(size, padding); // encap gen_find_size(data, size, padding); dsh2.message_length_ = static_cast<ACE_UINT32>(size + padding); elements[index].sample_ = new ACE_Message_Block(DataSampleHeader::max_marshaled_size(), ACE_Message_Block::MB_DATA, new ACE_Message_Block(dsh2.message_length_)); *elements[index].sample_ << dsh2; Serializer ser3(elements[index].sample_->cont(), host_is_bigendian, Serializer::ALIGN_CDR); ok = (ser3 << encap) && (ser3 << data.key) && (ser3 << data.value); if (!ok) { std::cerr << "ERROR: failed to serialize data for elements[" << index << "]\n"; return 1; } sdw.callbacks_expected_ = list.size(); ::DDS_TEST::force_inline_qos(true); // Inline QoS sdw.send(list); while (sdw.callbacks_expected_) { ACE_OS::sleep(1); } // Allow enough time for a HEARTBEAT message to be generated ACE_OS::sleep(rtps_inst->heartbeat_period_ * 2.0); // 3. cleanup sdw.disassociate(subscription.remote_id_); TheServiceParticipant->shutdown(); ACE_Thread_Manager::instance()->wait(); return 0; }
int ACE_TMAIN(int argc, ACE_TCHAR* argv[]) { try { TheParticipantFactoryWithArgs(argc, argv); std::cerr << "STARTING MAIN IN SUBSCRIBER\n"; ACE_TString host; u_short port = 0; ACE_Get_Opt opts(argc, argv, ACE_TEXT("h:p:")); int option = 0; while ((option = opts()) != EOF) { switch (option) { case 'h': host = opts.opt_arg(); break; case 'p': port = static_cast<u_short>(ACE_OS::atoi(opts.opt_arg())); break; } } if (host.empty() || port == 0) { std::cerr << "ERROR: -h <host> and -p <port> options are required\n"; return 1; } TransportInst_rch inst = TheTransportRegistry->create_inst("my_rtps", "rtps_udp"); RtpsUdpInst* rtps_inst = dynamic_cast<RtpsUdpInst*>(inst.in()); #ifdef OPENDDS_SAFETY_PROFILE if (host == "localhost") { host = "127.0.0.1"; } #endif rtps_inst->local_address(port, ACE_TEXT_ALWAYS_CHAR(host.c_str())); rtps_inst->datalink_release_delay_ = 0; TransportConfig_rch cfg = TheTransportRegistry->create_config("cfg"); cfg->instances_.push_back(inst); TheTransportRegistry->global_config(cfg); RepoIdBuilder local; local.federationId(0x01234567); // guidPrefix1 local.participantId(0xefcdab89); // guidPrefix2 local.entityKey(0x452310); local.entityKind(ENTITYKIND_USER_READER_WITH_KEY); RepoIdBuilder remote; // these values must match what's in publisher.cpp remote.federationId(0x01234567); // guidPrefix1 remote.participantId(0x89abcdef); // guidPrefix2 remote.entityKey(0x012345); remote.entityKind(ENTITYKIND_USER_WRITER_WITH_KEY); SimpleDataReader sdr(local); sdr.enable_transport(false /*reliable*/, false /*durable*/); // Write a file so that test script knows we're ready FILE* file = std::fopen("subready.txt", "w"); std::fprintf(file, "Ready\n"); std::fclose(file); std::cerr << "***Ready written to subready.txt\n"; AssociationData publication; publication.remote_id_ = remote; publication.remote_reliable_ = true; publication.remote_data_.length(1); publication.remote_data_[0].transport_type = "rtps_udp"; publication.remote_data_[0].data.length(5); for (CORBA::ULong i = 0; i < 5; ++i) { publication.remote_data_[0].data[i] = 0; } std::cerr << "***Association Data created for Publication for SimpleDataReader to init\n"; std::cout << "Associating with pub..." << std::endl; if (!sdr.init(publication)) { std::cerr << "subscriber TransportClient::associate() failed\n"; return 1; } std::cerr << "***Simple Data Reader init:: publication completed\n"; while (!sdr.done_) { ACE_OS::sleep(1); } if (sdr.control_msg_count_ != 4) { ACE_DEBUG((LM_ERROR, "ERROR: Expected 4 control messages, received %d\n", sdr.control_msg_count_)); } sdr.disassociate(publication.remote_id_); TheServiceParticipant->shutdown(); ACE_Thread_Manager::instance()->wait(); return 0; } catch (const OpenDDS::DCPS::Transport::NotConfigured& ) { ACE_DEBUG((LM_ERROR, "ERROR: caught OpenDDS::DCPS::Transport::NotConfigured exception.\n")); return 1; } catch (const CORBA::BAD_PARAM& ex) { ex._tao_print_exception("Exception caught in subscriber.cpp:"); return 1; } }