예제 #1
0
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)
      ));
    }
  }
}
예제 #2
0
/**
 * @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 ();
      }
  }

}
예제 #3
0
/**
 * @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 ();
    }

}
예제 #4
0
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")
  ));

}
예제 #5
0
/**
 * @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 ();
  }
}
예제 #6
0
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()
      ));
    }
  }
}
예제 #7
0
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")
  ));

}
예제 #8
0
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")
      ));
    }
  }
}
예제 #9
0
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")
    ));
  }

}