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(); } } }
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; } }