Publisher::Publisher( const Options& options) : status_( 0), options_( options), participant_(0), publisher_(0), waiter_( new DDS::WaitSet) { DDS::DomainParticipantFactory_var dpf = TheParticipantFactory; // Create the DomainParticipant this->participant_ = dpf->create_participant( this->options_.domain(), PARTICIPANT_QOS_DEFAULT, DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->participant_.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("failed to create a participant.\n") )); throw BadParticipantException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created participant in domain %d.\n"), this->options_.domain() )); } // Create and register the type support. DataTypeSupportImpl* testData = new DataTypeSupportImpl(); CORBA::String_var type_name = testData->get_type_name(); if( ::DDS::RETCODE_OK != testData->register_type( this->participant_.in(), 0)) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("unable to install type %C support.\n"), type_name.in() )); throw BadTypeSupportException (); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created type %C support.\n"), type_name.in() )); } // Create the topic. DDS::Topic_var topic = this->participant_->create_topic( this->options_.topicName().c_str(), type_name, TOPIC_QOS_DEFAULT, ::DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( topic.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("failed to create topic %C.\n"), this->options_.topicName().c_str() )); throw BadTopicException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created topic %C.\n"), this->options_.topicName().c_str() )); } // Create the publisher. this->publisher_ = this->participant_->create_publisher( PUBLISHER_QOS_DEFAULT, ::DDS::PublisherListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil(this->publisher_.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("failed to create publisher.\n") )); throw BadPublisherException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created publisher.\n") )); } // Writer Qos policy values. ::DDS::DataWriterQos writerQos; this->publisher_->get_default_datawriter_qos( writerQos); writerQos.durability.kind = ::DDS::TRANSIENT_LOCAL_DURABILITY_QOS; writerQos.history.kind = ::DDS::KEEP_ALL_HISTORY_QOS; writerQos.resource_limits.max_samples_per_instance = ::DDS::LENGTH_UNLIMITED; writerQos.reliability.kind = ::DDS::RELIABLE_RELIABILITY_QOS; if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("starting to create %d publications.\n"), this->options_.publications() )); } // Build as many publications as are specified. for( int index = 0; index < this->options_.publications(); ++index) { // Create the writer. DDS::DataWriter_var writer = this->publisher_->create_datawriter( topic.in(), writerQos, DDS::DataWriterListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( writer.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("failed to create writer.\n") )); throw BadWriterException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created publication %d.\n"), (1+index) )); } // Create a publication and store it. this->publications_.push_back( new Writer( writer.in(), index, this->options_.verbose()) ); // // Grab, enable and attach the status condition for test // synchronization of the current publication. // DDS::StatusCondition_var status = writer->get_statuscondition(); status->set_enabled_statuses( DDS::PUBLICATION_MATCHED_STATUS); this->waiter_->attach_condition( status.in()); if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created StatusCondition for publication %d.\n"), (1+index) )); } } }
/** * @brief Construct a test system from the command line. */ TestMonitor::TestMonitor( int argc, ACE_TCHAR** argv, char** envp) : config_( argc, argv, envp) { /// DDS_RUN_DEBUG_LEVEL = 5; /// OpenDDS::DCPS::DCPS_debug_level = 5; // Grab a local reference to the factory to ensure that we perform the // operations - they should not get optimized away! Note that this // passes the arguments to the ORB initialization first, then strips // the DCPS arguments. ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: initializing the monitor.\n"))); ::DDS::DomainParticipantFactory_var factory = TheParticipantFactoryWithArgs( argc, argv); this->subscriberParticipant_.resize( this->config_.subscriberDomainSize(), ::DDS::DomainParticipant::_nil() ); this->publisherParticipant_.resize( this->config_.publisherDomainSize(), ::DDS::DomainParticipant::_nil() ); this->subscriber_.resize( this->config_.subscriberDomainSize(), ::DDS::Subscriber::_nil()); this->publisher_.resize( this->config_.publisherDomainSize(), ::DDS::Publisher::_nil()); this->readerTopic_.resize( this->config_.subscriberDomainSize(), ::DDS::Topic::_nil()); this->writerTopic_.resize( this->config_.publisherDomainSize(), ::DDS::Topic::_nil()); this->dataReader_.resize( this->config_.subscriberDomainSize(), ::DDS::DataReader::_nil()); this->dataWriter_.resize( this->config_.publisherDomainSize(), ::DDS::DataWriter::_nil()); this->listener_.resize( this->config_.subscriberDomainSize(), ::DDS::DataReaderListener::_nil()); this->forwarder_.resize( this->config_.subscriberDomainSize(), 0); if( signed(OpenDDS::DCPS::DCPS_debug_level) >= 0) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T COMMANDLINE: Verbose == %C\n") ACE_TEXT("(%P|%t) %T COMMANDLINE: Samples == %d\n") ACE_TEXT("(%P|%t) %T COMMANDLINE: Type == %C\n") ACE_TEXT("(%P|%t) %T COMMANDLINE: Transport Address == %s\n"), (this->config_.verbose()? "true": "false"), this->config_.samples(), this->config_.typeName().c_str(), this->config_.transportAddressName().c_str() )); for( int index = 0; index < this->config_.infoRepoIorSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T COMMANDLINE: InforRepoIOR[ %d] == %C\n"), index, this->config_.infoRepoIor( index).c_str() )); } for( int index = 0; index < this->config_.readerTopicNameSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T COMMANDLINE: readerTopicName[ %d] == %C\n"), index, this->config_.readerTopicName( index).c_str() )); } for( int index = 0; index < this->config_.writerTopicNameSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T COMMANDLINE: writerTopicName[ %d] == %C\n"), index, this->config_.writerTopicName( index).c_str() )); } for( int index = 0; index < this->config_.subscriberDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T COMMANDLINE: subscriberDomain[ %d] == %d\n") ACE_TEXT("(%P|%t) %T COMMANDLINE: using repository key %d\n"), index, this->config_.subscriberDomain( index), this->config_.domainToRepo( this->config_.subscriberDomain( index)) )); } for( int index = 0; index < this->config_.publisherDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T COMMANDLINE: publisherDomain[ %d] == %d\n") ACE_TEXT("(%P|%t) %T COMMANDLINE: using repository key %d\n"), index, this->config_.publisherDomain( index), this->config_.domainToRepo( this->config_.publisherDomain( index)) )); } } for( int index = 0; index < this->config_.infoRepoIorSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: loading repository %d.\n"), index )); TheServiceParticipant->set_repo_ior( this->config_.infoRepoIor( index).c_str(), index ); } // We only need to do binding if we receive InfoRepo IOR values on the // command line - otherwise this is done during configuration file // processing. if( this->config_.infoRepoIorSize() > 0) { for( int index = 0; index < this->config_.subscriberDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: binding subscriber domain %d to repository %d.\n"), this->config_.subscriberDomain( index), this->config_.domainToRepo( this->config_.subscriberDomain( index)) )); TheServiceParticipant->set_repo_domain( this->config_.subscriberDomain( index), this->config_.domainToRepo( this->config_.subscriberDomain( index)) ); } for( int index = 0; index < this->config_.publisherDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: binding publisher domain %d to repository %d.\n"), this->config_.publisherDomain( index), this->config_.domainToRepo( this->config_.publisherDomain( index)) )); TheServiceParticipant->set_repo_domain( this->config_.publisherDomain( index), this->config_.domainToRepo( this->config_.publisherDomain( index)) ); } } // // Establish DomainParticipants for the subscription domains. // for( int index = 0; index < this->config_.subscriberDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating subscriber participant in domain %d.\n"), this->config_.subscriberDomain( index) )); ParticipantMap::iterator where = this->participants_.find( this->config_.subscriberDomain( index)); if( where == this->participants_.end()) { this->participants_[ this->config_.subscriberDomain( index)] = factory->create_participant( this->config_.subscriberDomain( index), PARTICIPANT_QOS_DEFAULT, ::DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if (CORBA::is_nil (this->participants_[ this->config_.subscriberDomain( index)].in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: create_participant failed for ") ACE_TEXT("subscriber[ %d] in domain %d.\n"), index, this->config_.subscriberDomain( index) )); throw BadParticipantException (); } } this->subscriberParticipant_[ index] = ::DDS::DomainParticipant::_duplicate (this->participants_[ this->config_.subscriberDomain( index)].in()); } // // Establish DomainParticipants for the publication domains. // for( int index = 0; index < this->config_.publisherDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating publisher participant in domain %d.\n"), this->config_.publisherDomain( index) )); ParticipantMap::iterator where = this->participants_.find( this->config_.publisherDomain( index)); if( where == this->participants_.end()) { this->participants_[ this->config_.publisherDomain( index)] = factory->create_participant( this->config_.publisherDomain( index), PARTICIPANT_QOS_DEFAULT, ::DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if (CORBA::is_nil (this->participants_[ this->config_.publisherDomain( index)].in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: create_participant failed for ") ACE_TEXT("publisher[ %d] in domain %d.\n"), index, this->config_.publisherDomain( index) )); throw BadParticipantException (); } } this->publisherParticipant_[ index] = ::DDS::DomainParticipant::_duplicate (this->participants_[ this->config_.publisherDomain( index)].in()); } // // Grab and install the transport implementations. // // We need to have a separate transport implementation for each // repository since the RepoId space will collide between them without // modification of the current implementation. // // Establish debug level. if( this->config_.verbose()) { TURN_ON_VERBOSE_DEBUG; } // // We have to extract the repository keys here since if we configured // the repositories and domains from a file, we do not have that // information available to us. Drat. // std::set< OpenDDS::DCPS::Service_Participant::RepoKey> keylist; for( int index = 0; index < this->config_.subscriberDomainSize(); ++index) { keylist.insert( TheServiceParticipant->domain_to_repo( this->config_.subscriberDomain( index))); } for( int index = 0; index < this->config_.publisherDomainSize(); ++index) { keylist.insert( TheServiceParticipant->domain_to_repo( this->config_.publisherDomain( index))); } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating transports for repositories.\n"))); ACE_UINT32 transportKey = 0; for( std::set< OpenDDS::DCPS::Service_Participant::RepoKey>::const_iterator current = keylist.begin(); current != keylist.end(); ++current, ++transportKey) { // Only create transports that need to be. if( false == TheTransportFactory->obtain( transportKey).is_nil()) { continue; } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating a SimpleTCP transport for repository: %d.\n"), *current )); this->transport_[ *current] = TheTransportFactory->create_transport_impl( transportKey, ACE_TEXT("SimpleTcp"), OpenDDS::DCPS::DONT_AUTO_CONFIG ); OpenDDS::DCPS::TransportConfiguration_rch reader_config = TheTransportFactory->create_configuration( transportKey, ACE_TEXT("SimpleTcp") ); // OpenDDS::DCPS::SimpleTcpConfiguration* reader_tcp_config // = static_cast <OpenDDS::DCPS::SimpleTcpConfiguration*>( reader_config.in() ); // // if( this->config_.transportAddressName().length() > 0) // { // ACE_INET_Addr reader_address( this->config_.transportAddressName().c_str()); // reader_tcp_config->local_address_ = reader_address; // reader_tcp_config->local_address_str_ = this->config_.transportAddressName(); // } // else use default address - OS assigned. if( this->transport_[ *current]->configure( reader_config.in()) != 0) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: TCP ") ACE_TEXT("failed to configure the transport.\n"))); throw BadTransportException (); } } // // Establish the listeners. // for( int index = 0; index < this->config_.subscriberDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating data reader listener for domain %d.\n"), this->config_.subscriberDomain( index) )); this->listener_[ index] = new ForwardingListenerImpl( TheServiceParticipant->domain_to_repo( this->config_.subscriberDomain( index) )); this->forwarder_[ index] = dynamic_cast<ForwardingListenerImpl*>(this->listener_[ index].in()); if (CORBA::is_nil (this->listener_[ index].in ())) { ACE_ERROR((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: failed to obtain listener for domain %d.\n"), this->config_.subscriberDomain( index) )); throw BadReaderListenerException (); } } // // Establish the Type Support for the data in each participant. (??) // for( ParticipantMap::const_iterator current = this->participants_.begin(); current != this->participants_.end(); ++current) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: Installing type %C support into domain %d.\n"), this->config_.typeName().c_str(), current->first )); if( 0 == CORBA::is_nil( current->second.in())) { ::Xyz::FooNoKeyTypeSupportImpl* subscriber_data = new ::Xyz::FooNoKeyTypeSupportImpl(); if(::DDS::RETCODE_OK != subscriber_data->register_type( current->second.in (), this->config_.typeName().c_str() ) ) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: Unable to install type %C support for domain %d.\n"), this->config_.typeName().c_str(), current->first )); throw TestException (); } } } // // Establish the Subscriber Topics. // for( int index = 0; index < this->config_.readerTopicNameSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating subscription[ %d] topic: %C.\n"), index, this->config_.readerTopicName( index).c_str() )); this->readerTopic_[ index] = this->participants_[ this->config_.subscriberDomain( index)]->create_topic( this->config_.readerTopicName( index).c_str(), this->config_.typeName().c_str(), TOPIC_QOS_DEFAULT, ::DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->readerTopic_[ index].in()) ) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to create topic %C for subscriber[ %d].\n"), this->config_.readerTopicName( index).c_str(), index )); throw BadTopicException (); } } // // Establish the Publisher Topics. // for( int index = 0; index < this->config_.writerTopicNameSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating publication[ %d] topic: %C.\n"), index, this->config_.writerTopicName( index).c_str() )); this->writerTopic_[ index] = this->participants_[ this->config_.publisherDomain( index)]->create_topic( this->config_.writerTopicName( index).c_str(), this->config_.typeName().c_str(), TOPIC_QOS_DEFAULT, ::DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->writerTopic_[ index].in()) ) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to create topic %C for publisher[ %d].\n"), this->config_.writerTopicName( index).c_str(), index )); throw BadTopicException (); } } // // Establish the Subscribers. // for( int index = 0; index < this->config_.subscriberDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating subscriber[ %d].\n"), index )); this->subscriber_[ index] = this->participants_[ this->config_.subscriberDomain( index)]->create_subscriber( SUBSCRIBER_QOS_DEFAULT, ::DDS::SubscriberListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (this->subscriber_[ index].in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to create_subscriber[ %d].\n"), index )); throw BadSubscriberException (); } // Attach the subscriber to the transport. OpenDDS::DCPS::SubscriberImpl* sub_impl = dynamic_cast<OpenDDS::DCPS::SubscriberImpl*>( this->subscriber_[ index].in () ); if (0 == sub_impl) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: Failed to obtain subscriber servant[ %d]\n"), index )); throw BadSubscriberException (); } OpenDDS::DCPS::AttachStatus attach_status; ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: attaching subscriber[ %d] to transport \n"), index )); attach_status = sub_impl->attach_transport( this->transport_[ TheServiceParticipant->domain_to_repo( this->config_.subscriberDomain( index)) ].in() ); if (attach_status != OpenDDS::DCPS::ATTACH_OK) { // We failed to attach to the transport for some reason. ACE_TString status_str; switch (attach_status) { case OpenDDS::DCPS::ATTACH_BAD_TRANSPORT: status_str = ACE_TEXT("ATTACH_BAD_TRANSPORT"); break; case OpenDDS::DCPS::ATTACH_ERROR: status_str = ACE_TEXT("ATTACH_ERROR"); break; case OpenDDS::DCPS::ATTACH_INCOMPATIBLE_QOS: status_str = ACE_TEXT("ATTACH_INCOMPATIBLE_QOS"); break; default: status_str = ACE_TEXT("Unknown Status"); break; } ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: Failed to attach to the transport. ") ACE_TEXT("AttachStatus == %s\n"), status_str.c_str())); throw BadTransportException (); } } // // Establish the Publishers. // for( int index = 0; index < this->config_.publisherDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating publisher[ %d].\n"), index )); this->publisher_[ index] = this->participants_[ this->config_.publisherDomain( index)]->create_publisher( PUBLISHER_QOS_DEFAULT, ::DDS::PublisherListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (this->publisher_[ index].in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to create_publisher[ %d].\n"), index )); throw BadSubscriberException (); } // Attach the publisher to the transport. OpenDDS::DCPS::PublisherImpl* pub_impl = dynamic_cast<OpenDDS::DCPS::PublisherImpl*>( this->publisher_[ index].in () ); if (0 == pub_impl) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: Failed to obtain publisher servant[ %d]\n"), index )); throw BadSubscriberException (); } OpenDDS::DCPS::AttachStatus attach_status; ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: attaching publisher[ %d] to transport \n"), index )); attach_status = pub_impl->attach_transport( this->transport_[ TheServiceParticipant->domain_to_repo( this->config_.publisherDomain( index)) ].in() ); if (attach_status != OpenDDS::DCPS::ATTACH_OK) { // We failed to attach to the transport for some reason. ACE_TString status_str; switch (attach_status) { case OpenDDS::DCPS::ATTACH_BAD_TRANSPORT: status_str = ACE_TEXT("ATTACH_BAD_TRANSPORT"); break; case OpenDDS::DCPS::ATTACH_ERROR: status_str = ACE_TEXT("ATTACH_ERROR"); break; case OpenDDS::DCPS::ATTACH_INCOMPATIBLE_QOS: status_str = ACE_TEXT("ATTACH_INCOMPATIBLE_QOS"); break; default: status_str = ACE_TEXT("Unknown Status"); break; } ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: Failed to attach to the transport. ") ACE_TEXT("AttachStatus == %s\n"), status_str.c_str())); throw BadTransportException (); } } // // Establish and install the DataWriter. // for( int index = 0; index < this->config_.publisherDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating datawriter[ %d].\n"), index )); ::DDS::DataWriterListener_var listener ( new DataWriterListenerImpl( TheServiceParticipant->domain_to_repo( this->config_.publisherDomain( index) ))); // // Keep all data samples to allow us to establish connections in an // arbitrary order, with samples being buffered at the first writer // that has not yet had a subscription match. // ::DDS::DataWriterQos writerQos; this->publisher_[ index]->get_default_datawriter_qos( writerQos); writerQos.durability.kind = ::DDS::TRANSIENT_LOCAL_DURABILITY_QOS; writerQos.history.kind = ::DDS::KEEP_ALL_HISTORY_QOS; writerQos.resource_limits.max_samples_per_instance = ::DDS::LENGTH_UNLIMITED; writerQos.reliability.kind = ::DDS::RELIABLE_RELIABILITY_QOS; writerQos.reliability.max_blocking_time.sec = 0; writerQos.reliability.max_blocking_time.nanosec = 0; this->dataWriter_[ index] = this->publisher_[ index]->create_datawriter(this->writerTopic_[ index].in(), writerQos, listener.in(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if( CORBA::is_nil( this->dataWriter_[ index].in()) ) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: create datawriter[ %d] failed.\n"), index )); throw BadWriterException (); } } for( unsigned int index = 1; index < this->forwarder_.size(); ++index) { // Pass the writer into the (previous) forwarder. this->forwarder_[ index - 1]->dataWriter( this->dataWriter_[ index].in()); } // The last forwarder does not. this->forwarder_[ this->forwarder_.size() - 1]->dataWriter( ::DDS::DataWriter::_nil() ); // // Establish and install the DataReader. This needs to be done after // the writer has been created and attached since it is possible (I // know, I've seen it happen!) that messages can be received and // forwarded between the time the reader is created and the writer is // created and attached to the forwarder if we do it the other way // round. // for( int index = 0; index < this->config_.subscriberDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating data reader[ %d].\n"), index )); ::DDS::TopicDescription_var description = this->participants_[ this->config_.subscriberDomain( index)]->lookup_topicdescription( this->config_.readerTopicName( index).c_str() ); this->dataReader_[ index] = this->subscriber_[ index]->create_datareader( description.in(), DATAREADER_QOS_DEFAULT, this->listener_[ index].in (), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->dataReader_[ index].in()) ) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: create datareader[ %d] failed.\n"), index )); throw BadReaderException (); } } }
/** * @brief Construct a test system from the command line. */ TestSystem::TestSystem( int argc, ACE_TCHAR** argv, char** envp) : config_( argc, argv, envp) , subscriberParticipant_(0) , publisherParticipant_(0) , subscriber_(0) , publisher_(0) , readerTopic_(0) , writerTopic_(0) , dataReader_(0) , dataWriter_(0) , listener_(0) , transport_() { // Grab a local reference to the factory to ensure that we perform the // operations - they should not get optimized away! Note that this // passes the arguments to the ORB initialization first, then strips // the DCPS arguments. ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: initializing the service.%d\n"), this->config_.infoRepoIorSize())); ::DDS::DomainParticipantFactory_var factory = TheParticipantFactoryWithArgs( argc, argv); // We only need to do loading and binding if we receive InfoRepo IOR // values on the command line - otherwise this is done during // configuration file processing. if( this->config_.infoRepoIorSize() > 0) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: loading repository %C.\n"), OpenDDS::DCPS::Discovery::DEFAULT_REPO )); TheServiceParticipant->set_repo_ior( this->config_.infoRepoIor().c_str()); ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: binding subscriber domain to repository %C.\n"), OpenDDS::DCPS::Discovery::DEFAULT_REPO )); TheServiceParticipant->set_repo_domain( this->config_.subscriberDomain(), OpenDDS::DCPS::Discovery::DEFAULT_REPO ); ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: binding publisher domain to repository %C.\n"), OpenDDS::DCPS::Discovery::DEFAULT_REPO )); TheServiceParticipant->set_repo_domain( this->config_.publisherDomain(), OpenDDS::DCPS::Discovery::DEFAULT_REPO ); #if 1 TheServiceParticipant->monitor_factory_->initialize(); #endif } // // Establish a DomainParticipant for the subscription domain. // ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating subscriber participant in domain %d.\n"), this->config_.subscriberDomain() )); this->subscriberParticipant_ = factory->create_participant( this->config_.subscriberDomain(), PARTICIPANT_QOS_DEFAULT, ::DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if (CORBA::is_nil (this->subscriberParticipant_.in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: create_participant failed for subscriber.\n"))); throw BadParticipantException (); } // // Establish a DomainParticipant for the publication domain. // ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating publisher participant in domain %d.\n"), this->config_.publisherDomain() )); if( this->config_.publisherDomain() == this->config_.subscriberDomain()) { // // Just reference the same participant for both activities if they // are in the same domain. // this->publisherParticipant_ = ::DDS::DomainParticipant::_duplicate(this->subscriberParticipant_.in()); } else { this->publisherParticipant_ = factory->create_participant( this->config_.publisherDomain(), PARTICIPANT_QOS_DEFAULT, ::DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if (CORBA::is_nil (this->publisherParticipant_.in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: create_participant failed for publisher.\n"))); throw BadParticipantException (); } } // // Grab and install the transport implementation. // NOTE: Try to use a single transport first. This is something that // needs to be verified and documented. // // Establish debug level. if( this->config_.verbose()) { TURN_ON_VERBOSE_DEBUG; } // // Establish a listener to install into the DataReader. // ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating data reader listener.\n"))); this->listener_ = new ForwardingListenerImpl(OpenDDS::DCPS::Discovery::DEFAULT_REPO); ForwardingListenerImpl* forwarder_servant = dynamic_cast<ForwardingListenerImpl*>(listener_.in()); if (CORBA::is_nil (this->listener_.in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: listener is nil.\n"))); throw BadReaderListenerException (); } // // Establish the Type Support for the data. // MJM: Do we need to have two distinct instantiations here? Or can we // share the servant across domains? // ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating subscription type support for type %C.\n"), this->config_.typeName().c_str() )); ::Xyz::FooNoKeyTypeSupport_var subscriber_data = new ::Xyz::FooNoKeyTypeSupportImpl(); if(::DDS::RETCODE_OK != subscriber_data->register_type( this->subscriberParticipant_.in (), this->config_.typeName().c_str() ) ) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to register the subscriber FooNoKeyTypeSupport.\n"))); throw TestException (); } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating publication type support for type %C.\n"), this->config_.typeName().c_str() )); ::Xyz::FooNoKeyTypeSupport_var publisher_data = new ::Xyz::FooNoKeyTypeSupportImpl(); if(::DDS::RETCODE_OK != publisher_data->register_type( this->publisherParticipant_.in (), this->config_.typeName().c_str() ) ) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to register the publisher FooNoKeyTypeSupport.\n"))); throw TestException (); } // // Establish the Subscriber and Publisher Topics. // ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating subscription topic: %C.\n"), this->config_.readerTopicName().c_str() )); this->readerTopic_ = this->subscriberParticipant_->create_topic( this->config_.readerTopicName().c_str(), this->config_.typeName().c_str(), TOPIC_QOS_DEFAULT, ::DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->readerTopic_.in()) ) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to create_topic for subscriber.\n"))); throw BadTopicException (); } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating publication topic: %C.\n"), this->config_.writerTopicName().c_str() )); this->writerTopic_ = this->publisherParticipant_->create_topic( this->config_.writerTopicName().c_str(), this->config_.typeName().c_str(), TOPIC_QOS_DEFAULT, ::DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->readerTopic_.in()) ) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to create_topic for publisher.\n"))); throw BadTopicException (); } // // Establish the Subscriber. // ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating subscriber.\n"))); this->subscriber_ = this->subscriberParticipant_->create_subscriber( SUBSCRIBER_QOS_DEFAULT, ::DDS::SubscriberListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (this->subscriber_.in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to create_subscriber.\n"))); throw BadSubscriberException (); } // // Establish the Publisher. // ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating publisher.\n"))); this->publisher_ = this->publisherParticipant_->create_publisher( PUBLISHER_QOS_DEFAULT, ::DDS::PublisherListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (this->publisher_.in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to create_publisher.\n"))); throw BadPublisherException (); } // // Establish and install the DataWriter. // ::DDS::DataWriterListener_var listener (new DataWriterListenerImpl(OpenDDS::DCPS::Discovery::DEFAULT_REPO)); // // Keep all data samples to allow us to establish connections in an // arbitrary order, with samples being buffered at the first writer // that has not yet had a subscription match. // ::DDS::DataWriterQos writerQos; this->publisher_->get_default_datawriter_qos( writerQos); writerQos.durability.kind = ::DDS::TRANSIENT_LOCAL_DURABILITY_QOS; writerQos.history.kind = ::DDS::KEEP_ALL_HISTORY_QOS; writerQos.resource_limits.max_samples_per_instance = ::DDS::LENGTH_UNLIMITED; writerQos.reliability.kind = ::DDS::RELIABLE_RELIABILITY_QOS; writerQos.reliability.max_blocking_time.sec = 0; writerQos.reliability.max_blocking_time.nanosec = 0; ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating data writer.\n"))); this->dataWriter_ = this->publisher_->create_datawriter( this->writerTopic_.in(), writerQos, listener.in(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->dataWriter_.in()) ) { ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: create_datawriter failed.\n"))); throw BadWriterException (); } // Pass the writer into the forwarder. forwarder_servant->dataWriter( this->dataWriter_.in()); // // Establish and install the DataReader. This needs to be done after // the writer has been created and attached since it is possible (I // know, I've seen it happen!) that messages can be received and // forwarded between the time the reader is created and the writer is // created and attached to the forwarder if we do it the other way // round. // ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: looking up subscription topic.\n"))); ::DDS::TopicDescription_var description = this->subscriberParticipant_->lookup_topicdescription( this->config_.readerTopicName().c_str() ); ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating data reader for topic: %C, type: %C.\n"), CORBA::String_var(description->get_name()).in(), CORBA::String_var(description->get_type_name()).in() )); this->dataReader_ = this->subscriber_->create_datareader( description.in(), DATAREADER_QOS_DEFAULT, this->listener_.in (), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->dataReader_.in()) ) { ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: create_datareader failed.\n"))); throw BadReaderException (); } }
Subscriber::Subscriber( const Options& options) : options_( options), listener_( 0), waiter_( new DDS::WaitSet) { DDS::DomainParticipantFactory_var dpf = TheParticipantFactory; // Create the DomainParticipant this->participant_ = dpf->create_participant( this->options_.domain(), PARTICIPANT_QOS_DEFAULT, DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->participant_.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to create a participant.\n") )); throw BadParticipantException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created participant in domain %d.\n"), this->options_.domain() )); } // Create the listener. this->listener_ = new DataReaderListener( this->options_.verbose()); this->safe_listener_ = this->listener_; ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created reader listener.\n") )); // Create and register the type support. DataTypeSupportImpl::_var_type testData = new DataTypeSupportImpl(); CORBA::String_var type_name = testData->get_type_name(); if( ::DDS::RETCODE_OK != testData->register_type( this->participant_.in(), 0)) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("unable to install type %C support.\n"), type_name.in() )); throw BadTypeSupportException (); } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created type %C support.\n"), type_name.in() )); // Create the topic. this->topic_ = this->participant_->create_topic( this->options_.topicName().c_str(), type_name, TOPIC_QOS_DEFAULT, ::DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->topic_.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to create topic %C.\n"), this->options_.topicName().c_str() )); throw BadTopicException(); } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created topic %C.\n"), this->options_.topicName().c_str() )); // Create the subscriber. this->subscriber_ = this->participant_->create_subscriber( SUBSCRIBER_QOS_DEFAULT, ::DDS::SubscriberListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->subscriber_.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to create subscriber.\n") )); throw BadSubscriberException(); } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created subscriber.\n") )); // Reader Qos policy values. ::DDS::DataReaderQos readerQos; this->subscriber_->get_default_datareader_qos( readerQos); // readerQos.durability.kind = ::DDS::TRANSIENT_LOCAL_DURABILITY_QOS; readerQos.history.kind = ::DDS::KEEP_ALL_HISTORY_QOS; readerQos.history.depth = 1; readerQos.destination_order.kind = ::DDS::BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS; // readerQos.resource_limits.max_samples_per_instance = ::DDS::LENGTH_UNLIMITED; // Reliability varies with the transport implementation. switch( this->options_.transportType()) { case Options::TCP: case Options::MC: readerQos.reliability.kind = ::DDS::RELIABLE_RELIABILITY_QOS; break; case Options::UDP: readerQos.reliability.kind = ::DDS::BEST_EFFORT_RELIABILITY_QOS; break; case Options::TRANSPORT_NONE: default: ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("unrecognized transport when setting up Qos policies.\n") )); throw BadQosException(); } // Create the reader. this->reader_ = this->subscriber_->create_datareader( this->topic_.in(), readerQos, DDS::DataReaderListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->reader_.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to create reader.\n") )); throw BadReaderException(); } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created reader.\n") )); // Set the listener mask here so that we don't conflict with the // StatusCondition(s) that we want to wait on in the main thread. this->reader_->set_listener( this->listener_, DDS::DATA_AVAILABLE_STATUS); // Grab, enable and attach the status condition for test synchronization. this->status_ = this->reader_->get_statuscondition(); this->status_->set_enabled_statuses( DDS::SUBSCRIPTION_MATCHED_STATUS); if (this->waiter_->attach_condition( this->status_.in()) != DDS::RETCODE_OK) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to match subscription.\n") )); throw BadAttachException(); } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created StatusCondition and WaitSet for test synchronization.\n") )); }
/** * @brief Construct a test system from the command line. */ Publisher::Publisher( int argc, char** argv, char** envp) : config_( argc, argv, envp) { // Grab a local reference to the factory ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) INFO: initializing the publisher.\n"))); ::DDS::DomainParticipantFactory_var factory = TheParticipantFactoryWithArgs( argc, argv); if( OpenDDS::DCPS::DCPS_debug_level > 0) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) COMMANDLINE: Verbose == %s\n") ACE_TEXT("(%P|%t) COMMANDLINE: Samples == %d\n"), (this->config_.verbose()? "true": "false"), this->config_.samples() )); } // // Establish DomainParticipant // if( OpenDDS::DCPS::DCPS_debug_level > 0) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) INFO: creating publisher participant in domain %d.\n"), this->config_.domain() )); } this->participant_ = factory->create_participant( this->config_.domain(), PARTICIPANT_QOS_DEFAULT, ::DDS::DomainParticipantListener::_nil() ); if( CORBA::is_nil( this->participant_.in())) { ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: create_participant failed for ") ACE_TEXT("publisher in domain %d.\n"), this->config_.domain() )); throw BadParticipantException (); } // // Grab and install the transport implementation. // // Establish debug level. if( this->config_.verbose()) { TURN_ON_VERBOSE_DEBUG; } if( OpenDDS::DCPS::DCPS_debug_level > 0) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) INFO: creating a SimpleTCP transport.\n"))); } this->transport_ = TheTransportFactory->create_transport_impl( 0, "SimpleTcp", OpenDDS::DCPS::DONT_AUTO_CONFIG ); OpenDDS::DCPS::TransportConfiguration_rch transport_config = TheTransportFactory->create_configuration( 0, ACE_TString("SimpleTcp") ); #if 0 OpenDDS::DCPS::SimpleTcpConfiguration* tcp_config = static_cast <OpenDDS::DCPS::SimpleTcpConfiguration*>( transport_config.in() ); std::string address; if( address.length() > 0) { ACE_INET_Addr reader_address( address.c_str()); tcp_config->local_address_ = reader_address; } #endif if( this->transport_->configure( transport_config.in()) != 0) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: TCP ") ACE_TEXT("failed to configure the transport.\n") )); throw BadTransportException (); } // // Establish the Type Support for the data // if( OpenDDS::DCPS::DCPS_debug_level > 0) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) INFO: Installing type %s support into domain %d.\n"), this->config_.typeName().c_str(), this->config_.domain() )); } ::Xyz::FooNoKeyTypeSupportImpl* publisher_data = new ::Xyz::FooNoKeyTypeSupportImpl(); if(::DDS::RETCODE_OK != publisher_data->register_type( this->participant_.in(), this->config_.typeName().c_str() ) ) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Unable to install type %s support for domain %d.\n"), this->config_.typeName().c_str(), this->config_.domain() )); throw TestException (); } // // Establish the Topic // this->topic_ = this->participant_->create_topic( this->config_.topicName().c_str(), this->config_.typeName().c_str(), TOPIC_QOS_DEFAULT, ::DDS::TopicListener::_nil() ); if( CORBA::is_nil( this->topic_.in()) ) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) ERROR: Failed to create topic %s for publisher.\n"), this->config_.topicName().c_str() )); throw BadTopicException (); } // // Establish the Publisher // this->publisher_ = this->participant_->create_publisher( PUBLISHER_QOS_DEFAULT, ::DDS::PublisherListener::_nil() ); if( CORBA::is_nil (this->publisher_.in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) ERROR: Failed to create_publisher.\n"))); throw BadPublisherException (); } // Attach the publisher to the transport. OpenDDS::DCPS::PublisherImpl* pub_impl = dynamic_cast<OpenDDS::DCPS::PublisherImpl*>( this->publisher_.in() ); if (0 == pub_impl) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Failed to obtain publisher servant\n"))); throw BadPublisherException (); } OpenDDS::DCPS::AttachStatus attach_status; if( OpenDDS::DCPS::DCPS_debug_level > 0) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) INFO: attaching publisher to transport \n"))); } attach_status = pub_impl->attach_transport( this->transport_.in()); if (attach_status != OpenDDS::DCPS::ATTACH_OK) { // We failed to attach to the transport for some reason. ACE_TString status_str; switch (attach_status) { case OpenDDS::DCPS::ATTACH_BAD_TRANSPORT: status_str = "ATTACH_BAD_TRANSPORT"; break; case OpenDDS::DCPS::ATTACH_ERROR: status_str = "ATTACH_ERROR"; break; case OpenDDS::DCPS::ATTACH_INCOMPATIBLE_QOS: status_str = "ATTACH_INCOMPATIBLE_QOS"; break; default: status_str = "Unknown Status"; break; } ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Failed to attach to the transport. ") ACE_TEXT("AttachStatus == %s\n"), status_str.c_str())); throw BadTransportException (); } // // Establish and install the DataWriter. // if( OpenDDS::DCPS::DCPS_debug_level > 0) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) INFO: creating datawriter.\n"))); } // // Keep all data samples to allow us to establish connections in an // arbitrary order, with samples being buffered at the first writer // that has not yet had a subscription match. // ::DDS::DataWriterQos writerQos; this->publisher_->get_default_datawriter_qos( writerQos); writerQos.durability.kind = ::DDS::TRANSIENT_LOCAL_DURABILITY_QOS; writerQos.history.kind = ::DDS::KEEP_ALL_HISTORY_QOS; writerQos.resource_limits.max_samples_per_instance = ::DDS::LENGTH_UNLIMITED; writerQos.reliability.kind = ::DDS::RELIABLE_RELIABILITY_QOS; writerQos.reliability.max_blocking_time.sec = 0; writerQos.reliability.max_blocking_time.nanosec = 0; this->dataWriter_ = this->publisher_->create_datawriter( this->topic_.in(), writerQos, ::DDS::DataWriterListener::_nil() ); if( CORBA::is_nil( this->dataWriter_.in()) ) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: create datawriter failed.\n"))); throw BadWriterException (); } }
Publisher::Publisher( const Options& options) : options_( options), waiter_( new DDS::WaitSet) { DDS::DomainParticipantFactory_var dpf = TheParticipantFactory; // Create the DomainParticipant this->participant_ = dpf->create_participant( this->options_.domain(), PARTICIPANT_QOS_DEFAULT, DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->participant_.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("failed to create a participant.\n") )); throw BadParticipantException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created participant in domain %d.\n"), this->options_.domain() )); } // Create the transport. OpenDDS::DCPS::TransportConfig_rch transport = TheTransportRegistry->get_config(this->options_.transportKey()); if (transport.is_nil()) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to get %C transport.\n"), this->options_.transportKey().c_str() )); throw BadTransportException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created %C transport.\n"), this->options_.transportKey().c_str() )); } // Create and register the type support. DataTypeSupportImpl* testData = new DataTypeSupportImpl(); if( ::DDS::RETCODE_OK != testData->register_type( this->participant_.in(), 0)) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("unable to install type %C support.\n"), testData->get_type_name() )); throw BadTypeSupportException (); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created type %C support.\n"), testData->get_type_name() )); } // Create the topic. this->topic_ = this->participant_->create_topic( this->options_.topicName().c_str(), testData->get_type_name(), TOPIC_QOS_DEFAULT, ::DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->topic_.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("failed to create topic %C.\n"), this->options_.topicName().c_str() )); throw BadTopicException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created topic %C.\n"), this->options_.topicName().c_str() )); } // Create the publisher. this->publisher_ = this->participant_->create_publisher( PUBLISHER_QOS_DEFAULT, ::DDS::PublisherListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->publisher_.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("failed to create publisher.\n") )); throw BadPublisherException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created publisher.\n") )); } TheTransportRegistry->bind_config(transport, this->publisher_); if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("attached transport to publisher.\n") )); } // Writer Qos policy values. ::DDS::DataWriterQos writerQos; this->publisher_->get_default_datawriter_qos( writerQos); writerQos.durability.kind = ::DDS::TRANSIENT_LOCAL_DURABILITY_QOS; writerQos.history.kind = ::DDS::KEEP_ALL_HISTORY_QOS; writerQos.resource_limits.max_samples_per_instance = ::DDS::LENGTH_UNLIMITED; // Reliability varies with the transport implementation. switch( this->options_.transportType()) { case Options::TCP: case Options::MC: writerQos.reliability.kind = ::DDS::RELIABLE_RELIABILITY_QOS; break; case Options::UDP: writerQos.reliability.kind = ::DDS::BEST_EFFORT_RELIABILITY_QOS; break; case Options::TRANSPORT_NONE: default: ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("unrecognized transport when setting up Qos policies.\n") )); throw BadQosException(); } if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("starting to create %d publications.\n"), this->options_.profiles().size() )); } // Build as many publications as are specified. for( unsigned int index = 0; index < this->options_.profiles().size(); ++index) { // This publications priority is needed when creating the writer. writerQos.transport_priority.value = this->options_.profiles()[ index]->priority(); // Create the writer. DDS::DataWriter_var writer = this->publisher_->create_datawriter( this->topic_.in(), writerQos, DDS::DataWriterListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( writer.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("failed to create writer.\n") )); throw BadWriterException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created writer for publication %C ") ACE_TEXT("with priority %d.\n"), this->options_.profiles()[ index]->name().c_str(), writerQos.transport_priority.value )); } // Create a publication and store it. this->publications_[ this->options_.profiles()[ index]->name()] = new Writer( writer.in(), *this->options_.profiles()[ index], this->options_.verbose() ); // // Grab, enable and attach the status condition for test // synchronization of the current publication. // DDS::StatusCondition_var status = writer->get_statuscondition(); status->set_enabled_statuses( DDS::PUBLICATION_MATCHED_STATUS); this->waiter_->attach_condition( status.in()); if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created StatusCondition for publication %C.\n"), this->options_.profiles()[ index]->name().c_str() )); } } }
Publisher::Publisher( const Options& options) : options_( options), waiter_( new DDS::WaitSet) { DDS::DomainParticipantFactory_var dpf = TheParticipantFactory; // Create the DomainParticipant this->participant_ = dpf->create_participant( this->options_.domain(), PARTICIPANT_QOS_DEFAULT, DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->participant_.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("failed to create a participant.\n") )); throw BadParticipantException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created participant in domain %d.\n"), this->options_.domain() )); } // Create and register the type support. DataTypeSupportImpl::_var_type testData = new DataTypeSupportImpl(); CORBA::String_var type_name = testData->get_type_name(); if( ::DDS::RETCODE_OK != testData->register_type( this->participant_.in(), 0)) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("unable to install type %C support.\n"), type_name.in() )); throw BadTypeSupportException (); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created type %C support.\n"), type_name.in() )); } // Create the topic. this->topic_ = this->participant_->create_topic( this->options_.topicName().c_str(), type_name, TOPIC_QOS_DEFAULT, ::DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->topic_.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("failed to create topic %C.\n"), this->options_.topicName().c_str() )); throw BadTopicException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created topic %C.\n"), this->options_.topicName().c_str() )); } // Create the publisher. this->publisher_ = this->participant_->create_publisher( PUBLISHER_QOS_DEFAULT, ::DDS::PublisherListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->publisher_.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("failed to create publisher.\n") )); throw BadPublisherException(); } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created publisher.\n") )); // Writer Qos policy values. ::DDS::DataWriterQos writerQos; this->publisher_->get_default_datawriter_qos( writerQos); // writerQos.durability.kind = ::DDS::TRANSIENT_LOCAL_DURABILITY_QOS; writerQos.history.kind = ::DDS::KEEP_ALL_HISTORY_QOS; // this number is set to have a big enough queue of data to see that the higher priority // message is on its own queue, if tests start failing, then this number should be increased // or possibly sample0.baggage length increased writerQos.resource_limits.max_samples_per_instance = 100; writerQos.resource_limits.max_samples = 100; // Reliability varies with the transport implementation. writerQos.reliability.max_blocking_time.sec = 1; writerQos.reliability.max_blocking_time.nanosec = 0; switch( this->options_.transportType()) { case Options::TCP: case Options::MC: writerQos.reliability.kind = ::DDS::RELIABLE_RELIABILITY_QOS; break; case Options::UDP: writerQos.reliability.kind = ::DDS::BEST_EFFORT_RELIABILITY_QOS; break; case Options::TRANSPORT_NONE: default: ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("unrecognized transport when setting up Qos policies.\n") )); throw BadQosException(); } // Create the writer. this->writer_[0] = this->publisher_->create_datawriter( this->topic_.in(), writerQos, DDS::DataWriterListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->writer_[0].in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("failed to create writer[0].\n") )); throw BadWriterException(); } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created writer[0].\n") )); // Grab, enable and attach the status condition for test synchronization. this->status_[0] = this->writer_[0]->get_statuscondition(); this->status_[0]->set_enabled_statuses( DDS::PUBLICATION_MATCHED_STATUS); if (this->waiter_->attach_condition( this->status_[0].in()) != DDS::RETCODE_OK) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("failed to match publication.\n") )); throw BadAttachException(); } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created StatusCondition[0] for test synchronization.\n") )); // Actually set the priority finally. writerQos.transport_priority.value = this->options_.priority(); // Create the writer. this->writer_[1] = this->publisher_->create_datawriter( this->topic_.in(), writerQos, DDS::DataWriterListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->writer_[1].in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("failed to create writer[1].\n") )); throw BadWriterException(); } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created writer[1].\n") )); // Grab, enable and attach the status condition for test synchronization. this->status_[1] = this->writer_[1]->get_statuscondition(); this->status_[1]->set_enabled_statuses( DDS::PUBLICATION_MATCHED_STATUS); if (this->waiter_->attach_condition( this->status_[1].in()) != DDS::RETCODE_OK) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publisher::Publisher() - ") ACE_TEXT("failed to match publication.\n") )); throw BadAttachException(); } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Publisher::Publisher() - ") ACE_TEXT("created StatusCondition[1] for test synchronization.\n") )); }
Subscriber::Subscriber( const Options& options) : options_( options), waiter_( new DDS::WaitSet) { // Create the DomainParticipant this->participant_ = TheParticipantFactory->create_participant( this->options_.domain(), PARTICIPANT_QOS_DEFAULT, DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->participant_.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to create a participant.\n") )); throw BadParticipantException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created participant in domain %d.\n"), this->options_.domain() )); } // Create and register the type support. DataTypeSupportImpl* testData = new DataTypeSupportImpl(); if( ::DDS::RETCODE_OK != testData->register_type( this->participant_.in(), 0)) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("unable to install type %C support.\n"), testData->get_type_name() )); throw BadTypeSupportException (); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created type %C support.\n"), testData->get_type_name() )); } // Create the topic. DDS::Topic_var topic = this->participant_->create_topic( this->options_.topicName().c_str(), testData->get_type_name(), TOPIC_QOS_DEFAULT, ::DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( topic.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to create topic %C.\n"), this->options_.topicName().c_str() )); throw BadTopicException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created topic %C.\n"), this->options_.topicName().c_str() )); } // Create the subscriber. DDS::Subscriber_var subscriber = this->participant_->create_subscriber( SUBSCRIBER_QOS_DEFAULT, ::DDS::SubscriberListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( subscriber.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to create subscriber.\n") )); throw BadSubscriberException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created subscriber.\n") )); } // Create the transport. OpenDDS::DCPS::TransportImpl_rch transport = TheTransportFactory->create_transport_impl( this->options_.transportKey(), OpenDDS::DCPS::AUTO_CONFIG ); if( transport.is_nil()) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to create transport.\n") )); throw BadTransportException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created transport.\n") )); } // Attach the transport. if( ::OpenDDS::DCPS::ATTACH_OK != transport->attach( subscriber.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to attach subscriber to transport.\n") )); throw BadAttachException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("attached subscriber to transport.\n") )); } // Reader Qos policy values. ::DDS::DataReaderQos readerQos; subscriber->get_default_datareader_qos( readerQos); readerQos.reliability.kind = ::DDS::RELIABLE_RELIABILITY_QOS; // Create the readers. for( int index = 0; index < 2; ++index) { ::DDS::DataReader_var reader = subscriber->create_datareader( topic.in(), readerQos, DDS::DataReaderListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( reader.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to create reader.\n") )); throw BadReaderException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created reader.\n") )); } this->reader_[ index] = ::OpenDDS::DCPS::DataReaderEx::_narrow( reader.in()); if( CORBA::is_nil( this->reader_[ index].in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to narrow reader to extract statistics.\n") )); throw BadReaderException(); } // Grab, enable and attach the status condition for test synchronization. this->status_ = this->reader_[ index]->get_statuscondition(); this->status_->set_enabled_statuses( DDS::SUBSCRIPTION_MATCHED_STATUS); this->waiter_->attach_condition( this->status_.in()); if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created StatusCondition and WaitSet for test synchronization.\n") )); } } }
Subscriber::Subscriber( const Options& options) : options_( options), listener_( 0), waiter_( new DDS::WaitSet) { DDS::DomainParticipantFactory_var dpf = TheParticipantFactory; // Create the DomainParticipant this->participant_ = dpf->create_participant( this->options_.domain(), PARTICIPANT_QOS_DEFAULT, DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->participant_.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to create a participant.\n") )); throw BadParticipantException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created participant in domain %d.\n"), this->options_.domain() )); } // Create the transport. OpenDDS::DCPS::TransportConfig_rch transport = TheTransportRegistry->get_config(this->options_.transportKey()); if (transport.is_nil()) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to get %C transport.\n"), this->options_.transportKey().c_str() )); throw BadTransportException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created %C transport.\n"), this->options_.transportKey().c_str() )); } // Create the listener. this->listener_ = new DataReaderListener( this->options_.verbose()); this->safe_listener_ = this->listener_; if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created reader listener.\n") )); } // Create and register the type support. DataTypeSupportImpl* testData = new DataTypeSupportImpl(); if( ::DDS::RETCODE_OK != testData->register_type( this->participant_.in(), 0)) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("unable to install type %C support.\n"), testData->get_type_name() )); throw BadTypeSupportException (); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created type %C support.\n"), testData->get_type_name() )); } // Create the topic. this->topic_ = this->participant_->create_topic( this->options_.topicName().c_str(), testData->get_type_name(), TOPIC_QOS_DEFAULT, ::DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->topic_.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to create topic %C.\n"), this->options_.topicName().c_str() )); throw BadTopicException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created topic %C.\n"), this->options_.topicName().c_str() )); } // Create the subscriber. this->subscriber_ = this->participant_->create_subscriber( SUBSCRIBER_QOS_DEFAULT, ::DDS::SubscriberListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->subscriber_.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to create subscriber.\n") )); throw BadSubscriberException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created subscriber.\n") )); } // Attach the transport to the subscriber. ::OpenDDS::DCPS::SubscriberImpl* servant = dynamic_cast< ::OpenDDS::DCPS::SubscriberImpl*>( this->subscriber_.in()); if( 0 == servant) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to narrow subscriber servant.\n") )); throw BadServantException(); } // Configure the raw data gathering. servant->raw_latency_buffer_size() = this->options_.raw_buffer_size(); servant->raw_latency_buffer_type() = this->options_.raw_buffer_type(); if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("configured to capture %d latency measurements of type %d ") ACE_TEXT("per writer to file %C.\n"), this->options_.raw_buffer_size(), this->options_.raw_buffer_type(), this->options_.rawOutputFilename().c_str() )); } TheTransportRegistry->bind_config(transport, servant); if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("attached transport to subscriber.\n") )); } // Reader Qos policy values. ::DDS::DataReaderQos readerQos; this->subscriber_->get_default_datareader_qos( readerQos); readerQos.durability.kind = ::DDS::TRANSIENT_LOCAL_DURABILITY_QOS; readerQos.history.kind = ::DDS::KEEP_ALL_HISTORY_QOS; readerQos.resource_limits.max_samples_per_instance = ::DDS::LENGTH_UNLIMITED; // Reliability varies with the transport implementation. switch( this->options_.transportType()) { case Options::TCP: case Options::MC: readerQos.reliability.kind = ::DDS::RELIABLE_RELIABILITY_QOS; break; case Options::UDP: readerQos.reliability.kind = ::DDS::BEST_EFFORT_RELIABILITY_QOS; break; case Options::TRANSPORT_NONE: default: ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("unrecognized transport when setting up Qos policies.\n") )); throw BadQosException(); } // Create the reader. ::DDS::DataReader_var reader = this->subscriber_->create_datareader( this->topic_.in(), readerQos, DDS::DataReaderListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( reader.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to create reader.\n") )); throw BadReaderException(); } else if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created reader.\n") )); } this->reader_ = ::OpenDDS::DCPS::DataReaderEx::_narrow( reader.in()); if( CORBA::is_nil( this->reader_.in())) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Subscriber::Subscriber() - ") ACE_TEXT("failed to narrow reader to extract statistics.\n") )); throw BadReaderException(); } // Clear and start statistics gathering. Ideally we would want to // configurably delay the start here to avoid edge effects. this->reader_->reset_latency_stats(); this->reader_->statistics_enabled( true); // Set the listener mask here so that we don't conflict with the // StatusCondition(s) that we want to wait on in the main thread. this->reader_->set_listener( this->listener_, DDS::DATA_AVAILABLE_STATUS); // Grab, enable and attach the status condition for test synchronization. this->status_ = this->reader_->get_statuscondition(); this->status_->set_enabled_statuses( DDS::SUBSCRIPTION_MATCHED_STATUS); this->waiter_->attach_condition( this->status_.in()); if( this->options_.verbose()) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) Subscriber::Subscriber() - ") ACE_TEXT("created StatusCondition and WaitSet for test synchronization.\n") )); } }