Open-DDS源代码分析

本文详细介绍了OpenDDS源代码中的发布和订阅流程,包括创建DomainParticipant、Topic、Publisher、DataWriter以及Subscriber和DataReader的步骤。同时,解析了用户参数,并展示了如何处理配置文件。通过示例展示了OpenDDS内部的数据传输和关联过程。
摘要由CSDN通过智能技术生成

  1. 版本:

OpenDDS 3.21

  1. 测试程序主流程
    1. 配置文件

[common]

DCPSDefaultDiscovery=DEFAULT_RTPS

DCPSGlobalTransportConfig=$file

[transport/the_rtps_transport]

transport_type=rtps_udp

    1. 发布程序
      1. 创建一个DomainParticipantFactory

DDS::DomainParticipantFactory_var dpf = TheParticipantFactoryWithArgs(argc, argv)

      1. 创建一个DomainParticipant

DDS::DomainParticipant_var participant = dpf->create_participant(42,

                              PARTICIPANT_QOS_DEFAULT,

                              0,

                              OpenDDS::DCPS::DEFAULT_STATUS_MASK)

      1. 创建一个Topic

Messenger::MessageTypeSupport_var ts =new Messenger::MessageTypeSupportImpl

ts->register_type(participant, "")

CORBA::String_var type_name = ts->get_type_name();

DDS::Topic_var topic = participant->create_topic("Movie Discussion List",

                                type_name,

                                TOPIC_QOS_DEFAULT,

                                0,

                                OpenDDS::DCPS::DEFAULT_STATUS_MASK)

      1. 创建一个Publisher

DDS::Publisher_var publisher = participant->create_publisher(PUBLISHER_QOS_DEFAULT,

                                    0,

                                    OpenDDS::DCPS::DEFAULT_STATUS_MASK)

      1. 创建一个datawriter

DDS::DataWriter_var writer = publisher->create_datawriter(topic,

                                   DATAWRITER_QOS_DEFAULT,

                                   0,

                                   OpenDDS::DCPS::DEFAULT_STATUS_MASK)

      1. 创建一个messagedatawriter

Messenger::MessageDataWriter_var message_writer = Messenger::MessageDataWriter::_narrow(writer)

DDS::StatusCondition_var condition = writer->get_statuscondition()

      1. 构造一个消息

Messenger::Message message;

message.subject_id = 99;

 message.from       = "Comic Book Guy";

 message.subject    = "Review";

 message.text       = "Worst. Movie. Ever.";

 message.count      = 0;

      1. 循环发送消息

 for (int i = 0; i < 10; ++i) {

      DDS::ReturnCode_t error = message_writer->write(message, DDS::HANDLE_NIL)
}

    1. 订阅程序
      1. 创建一个DomainParticipantFactory

DDS::DomainParticipantFactory_var dpf = TheParticipantFactoryWithArgs(argc, argv)

      1. 创建一个DomainParticipant

DDS::DomainParticipant_var participant = dpf->create_participant(42,

                              PARTICIPANT_QOS_DEFAULT,

                              0,

                              OpenDDS::DCPS::DEFAULT_STATUS_MASK)

      1. 创建一个Topic

Messenger::MessageTypeSupport_var ts =new Messenger::MessageTypeSupportImpl

ts->register_type(participant, "")

CORBA::String_var type_name = ts->get_type_name();

DDS::Topic_var topic = participant->create_topic("Movie Discussion List",

                                type_name,

                                TOPIC_QOS_DEFAULT,

                                0,

                                OpenDDS::DCPS::DEFAULT_STATUS_MASK)

      1. 创建一个Subscriber

DDS::Subscriber_var subscriber =

      participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT,

                                     0,

                                     OpenDDS::DCPS::DEFAULT_STATUS_MASK);

      1. 创建一个datareader

DDS::DataReaderListener_var listener(new DataReaderListenerImpl);  // on_data_available()在这个类里面实现,用于接收消息

DDS::DataReaderQos reader_qos;  //QOS类型设置

subscriber->get_default_datareader_qos(reader_qos);

reader_qos.reliability.kind = DDS::RELIABLE_RELIABILITY_QOS;

DDS::DataReader_var reader =

subscriber->create_datareader(topic,

                                    reader_qos,

                                    listener,

                                    OpenDDS::DCPS::DEFAULT_STATUS_MASK);

      1. 创建一个messagedatareader

Messenger::MessageDataReader_var reader_i =

      Messenger::MessageDataReader::_narrow(reader);

      1. 接收消息

void

DataReaderListenerImpl::on_data_available(DDS::DataReader_ptr reader)

{

  Messenger::MessageDataReader_var reader_i =

  Messenger::MessageDataReader::_narrow(reader);

  Messenger::Message message;

  DDS::SampleInfo info;

  const DDS::ReturnCode_t error = reader_i->take_next_sample(message, info);

  if (error == DDS::RETCODE_OK) {

    std::cout << "SampleInfo.sample_rank = " << info.sample_rank << std::endl;

    std::cout << "SampleInfo.instance_state = " << OpenDDS::DCPS::InstanceState::instance_state_mask_string(info.instance_state) << std::endl;

    if (info.valid_data) {

      std::cout << "Message: subject    = " << message.subject.in() << std::endl

                << "         subject_id = " << message.subject_id   << std::endl

                << "         from       = " << message.from.in()    << std::endl

                << "         count      = " << message.count        << std::endl

                << "         text       = " << message.text.in()    << std::endl;

    }

}

  1. 如何解析用户参数

TheParticipantFactoryWithArgs(argc, argv)

TheParticipantFactoryWithArgs 定义如下:

#define TheParticipantFactoryWithArgs(argc, argv) TheServiceParticipant->get_domain_participant_factory(argc, argv)

所以,会调用到如下接口:

DDS::DomainParticipantFactory_ptr

Service_Participant::get_domain_participant_factory(int &argc,

                                                    ACE_TCHAR *argv[])

{

      if (parse_args(argc, argv) != 0) {

        return DDS::DomainParticipantFactory::_nil();

      }

        //如果 .ini 配置文件存在,则打开配置文件

        FILE* in = ACE_OS::fopen(config_fname.c_str(), ACE_TEXT("r"));

        if (this->load_configuration() != 0)

}

    1. Service_Participant::parse_args实现

int Service_Participant::parse_args(int& argc, ACE_TCHAR* argv[])

{

  // Process logging options first, so they are in effect if we need to log

  // while processing other options.

  ACE_Arg_Shifter log_arg_shifter(argc, argv);

  while (log_arg_shifter.is_anything_left()) {

    const ACE_TCHAR* currentArg = 0;

    if ((currentArg = log_arg_shifter.get_the_parameter(ACE_TEXT("-ORBLogFile"))) != 0) {

      set_log_file_name(ACE_TEXT_ALWAYS_CHAR(currentArg));

      log_arg_shifter.consume_arg();

      got_log_fname = true;

    } else if ((currentArg = log_arg_shifter.get_the_parameter(ACE_TEXT("-ORBVerboseLogging"))) != 0) {

      set_log_verbose(ACE_OS::atoi(currentArg));

      log_arg_shifter.consume_arg();

      got_log_verbose = true;

    } else {

      log_arg_shifter.ignore_arg();

    }

  }

  ACE_Arg_Shifter arg_shifter(argc, argv);

  while (arg_shifter.is_anything_left()) {

    const ACE_TCHAR* currentArg = 0;

    if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSDebugLevel"))) != 0) {

      set_DCPS_debug_level(ACE_OS::atoi(currentArg));

      arg_shifter.consume_arg();

      got_debug_level = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSInfoRepo"))) != 0) {

      this->set_repo_ior(currentArg, Discovery::DEFAULT_REPO);

      arg_shifter.consume_arg();

      got_info = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSRTISerialization"))) != 0) {

      if (ACE_OS::atoi(currentArg) == 0) {

        ACE_ERROR((LM_WARNING,

          ACE_TEXT("(%P|%t) WARNING: Service_Participant::parse_args ")

          ACE_TEXT("Argument ignored: DCPSRTISerialization is required to be enabled\n")));

      }

      arg_shifter.consume_arg();

      got_use_rti_serialization = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSChunks"))) != 0) {

      n_chunks_ = ACE_OS::atoi(currentArg);

      arg_shifter.consume_arg();

      got_chunks = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSChunkAssociationMultiplier"))) != 0) {

      association_chunk_multiplier_ = ACE_OS::atoi(currentArg);

      arg_shifter.consume_arg();

      got_chunk_association_multiplier = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSConfigFile"))) != 0) {  //如果用户传入了一个配置文件,则会使用该 ini 配置文件

      config_fname = currentArg;

      arg_shifter.consume_arg();

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSLivelinessFactor"))) != 0) {

      liveliness_factor_ = ACE_OS::atoi(currentArg);

      arg_shifter.consume_arg();

      got_liveliness_factor = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSBitTransportPort"))) != 0) {

      /// No need to guard this insertion as we are still single

      /// threaded here.

      this->bit_transport_port_ = ACE_OS::atoi(currentArg);

      arg_shifter.consume_arg();

      got_bit_transport_port = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSBitTransportIPAddress"))) != 0) {

      /// No need to guard this insertion as we are still single

      /// threaded here.

      this->bit_transport_ip_ = currentArg;

      arg_shifter.consume_arg();

      got_bit_transport_ip = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSBitLookupDurationMsec"))) != 0) {

      bit_lookup_duration_msec_ = ACE_OS::atoi(currentArg);

      arg_shifter.consume_arg();

      got_bit_lookup_duration_msec = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSGlobalTransportConfig"))) != 0) {

      global_transport_config_ = currentArg;

      arg_shifter.consume_arg();

      got_global_transport_config = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSBit"))) != 0) {

      bit_enabled_ = ACE_OS::atoi(currentArg);

      arg_shifter.consume_arg();

      got_bit_flag = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSTransportDebugLevel"))) != 0) {

      OpenDDS::DCPS::Transport_debug_level = ACE_OS::atoi(currentArg);

      arg_shifter.consume_arg();

      got_transport_debug_level = true;

#ifndef OPENDDS_NO_PERSISTENCE_PROFILE

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSPersistentDataDir"))) != 0) {

      this->persistent_data_dir_ = ACE_TEXT_ALWAYS_CHAR(currentArg);

      arg_shifter.consume_arg();

      got_persistent_data_dir = true;

#endif

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSPendingTimeout"))) != 0) {

      pending_timeout_ = TimeDuration(ACE_OS::atoi(currentArg));

      arg_shifter.consume_arg();

      got_pending_timeout = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSPublisherContentFilter"))) != 0) {

      this->publisher_content_filter_ = ACE_OS::atoi(currentArg);

      arg_shifter.consume_arg();

      got_publisher_content_filter = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSDefaultDiscovery"))) != 0) {

      this->defaultDiscovery_ = ACE_TEXT_ALWAYS_CHAR(currentArg);

      arg_shifter.consume_arg();

      got_default_discovery = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSBidirGIOP"))) != 0) {

      bidir_giop_ = ACE_OS::atoi(currentArg);

      arg_shifter.consume_arg();

      got_bidir_giop = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSThreadStatusInterval"))) != 0) {

      thread_status_manager_.thread_status_interval(TimeDuration(ACE_OS::atoi(currentArg)));

      arg_shifter.consume_arg();

      got_thread_status_interval = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-FederationRecoveryDuration"))) != 0) {

      this->federation_recovery_duration_ = ACE_OS::atoi(currentArg);

      arg_shifter.consume_arg();

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-FederationInitialBackoffSeconds"))) != 0) {

      this->federation_initial_backoff_seconds_ = ACE_OS::atoi(currentArg);

      arg_shifter.consume_arg();

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-FederationBackoffMultiplier"))) != 0) {

      this->federation_backoff_multiplier_ = ACE_OS::atoi(currentArg);

      arg_shifter.consume_arg();

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-FederationLivelinessDuration"))) != 0) {

      this->federation_liveliness_ = ACE_OS::atoi(currentArg);

      arg_shifter.consume_arg();

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSDefaultAddress"))) != 0) {

      ACE_INET_Addr addr;

      if (addr.set(u_short(0), currentArg)) {

        ACE_ERROR_RETURN((LM_ERROR,

                          ACE_TEXT("(%P|%t) ERROR: Service_Participant::parse_args: ")

                          ACE_TEXT("failed to parse default address %C\n"),

                          currentArg),

                         -1);

      }

      default_address_ = NetworkAddress(addr);

      arg_shifter.consume_arg();

      got_default_address = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSMonitor"))) != 0) {

      this->monitor_enabled_ = ACE_OS::atoi(currentArg);

      arg_shifter.consume_arg();

      got_monitor = true;

#if defined(OPENDDS_SECURITY)

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSSecurityDebugLevel"))) != 0) {

      security_debug.set_debug_level(ACE_OS::atoi(currentArg));

      arg_shifter.consume_arg();

      got_security_debug = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSSecurityDebug"))) != 0) {

      security_debug.parse_flags(currentArg);

      arg_shifter.consume_arg();

      got_security_debug = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSSecurityFakeEncryption"))) != 0) {

      security_debug.fake_encryption = ACE_OS::atoi(currentArg);

      arg_shifter.consume_arg();

      got_security_fake_encryption = true;

    // Must be last "-DCPSSecurity*" option, see comment above this arg parsing loop

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSSecurity"))) != 0) {

      security_enabled_ = ACE_OS::atoi(currentArg);

      arg_shifter.consume_arg();

      got_security_flag = true;

#endif

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSTypeObjectEncoding"))) != 0) {

      type_object_encoding(ACE_TEXT_ALWAYS_CHAR(currentArg));

      arg_shifter.consume_arg();

      got_type_object_encoding = true;

    } else if ((currentArg = arg_shifter.get_the_parameter(ACE_TEXT("-DCPSLogLevel"))) != 0) {

      log_level.set_from_string(ACE_TEXT_ALWAYS_CHAR(currentArg));

      arg_shifter.consume_arg();

      got_log_level = true;

    } else {

      arg_shifter.ignore_arg();

    }

  }

  // Indicates successful parsing of the command line

  return 0;

}

    1. Service_Participant::load_configuration 实现

int

Service_Participant::load_configuration()

{

  ACE_Configuration_Heap cf;

  int status = 0;

  ACE_Ini_ImpExp import(cf);

  status = import.import_config(config_fname.c_str());

   status = this->load_configuration(cf, config_fname.c_str());

  return status;

}

    1. Service_Participant::load_configuration

对于 INI 文件中,每个字段的解析,都是在这个函数中完成的

int

Service_Participant::load_configuration(

  ACE_Configuration_Heap& config,

  const ACE_TCHAR* filename)

{

  // Domain config is loaded after Discovery (see below). Since the domain

  // could be a domain_range that specifies the DiscoveryTemplate, check

  // for config templates before loading any config information.

  ACE_TString section_name;

  int status = this->load_common_configuration(config, filename);

  if (status != 0) {

    ACE_ERROR_RETURN((LM_ERROR,

                      ACE_TEXT("(%P|%t) ERROR: Service_Participant::load_configuration ")

                      ACE_TEXT("load_common_configuration () returned %d\n"),

                      status),

                     -1);

  }

  // Register static discovery.

  this->add_discovery(static_rchandle_cast<Discovery>(StaticDiscovery::instance()));

  // load any discovery configuration templates before rtps discovery

  // this will populate the domain_range_templates_

  status = this->load_domain_ranges(config);

  // load any rtps_discovery templates

  status = this->load_discovery_templates(config);

  status = this->load_discovery_configuration(config, RTPS_SECTION_NAME);

  status = this->load_discovery_configuration(config, REPO_SECTION_NAME);

  // load any transport configuration templates before the transport config

  status = TransportRegistry::instance()->load_transport_templates(config);

  status = TransportRegistry::instance()->load_transport_configuration(

             ACE_TEXT_ALWAYS_CHAR(filename), config);

  if (this->global_transport_config_ != ACE_TEXT("")) {

    TransportConfig_rch config = TransportRegistry::instance()->get_config(

      ACE_TEXT_ALWAYS_CHAR(this->global_transport_config_.c_str()));

    if (config) {

      TransportRegistry::instance()->global_config(config);

    } else if (TheTransportRegistry->config_has_transport_template(global_transport_config_)) {

         

  }

  // Needs to be loaded after the [rtps_discovery/*] and [repository/*]

  // sections to allow error reporting on bad discovery config names.

  // Also loaded after the transport configuration so that

  // DefaultTransportConfig within [domain/*] can use TransportConfig objects.

  status = this->load_domain_configuration(config, filename);

  // Needs to be loaded after transport configs and instances and domains.

  try {

    status = StaticDiscovery::instance()->load_configuration(config);

  return 0;

}

  1. 中心式管理进程InfoRepo

dds\InfoRepo\DCPSInfoRepo.cpp

int

ACE_TMAIN(int argc, ACE_TCHAR *argv[])

{

  try {

    InfoRepo infoRepo(argc, argv);

    InfoRepo_Shutdown ir_shutdown(infoRepo);

    Service_Shutdown service_shutdown(ir_shutdown);

    infoRepo.run();

  } catch (InfoRepo::InitError& ex) {

    std::cerr << "Unexpected initialization Error: "

              << ex.msg_ << std::endl;

    return 1;

  } catch (const CORBA::Exception& ex) {

    ex._tao_print_exception("ERROR: DDS DCPS Info Repo caught exception");

    return 1;

  }

  return 0;

}

InfoRepo::InfoRepo(int argc, ACE_TCHAR *argv[])

: ior_file_(ACE_TEXT("repo.ior"))

, listen_address_given_(0)

#ifdef DDS_HAS_MINIMUM_BIT

, use_bits_(false)

#else

, use_bits_(true)

#endif

, resurrect_(true)

, finalized_(false)

, servant_finalized_(false)

, federator_(this->federatorConfig_)

, federatorConfig_(argc, argv)

, lock_()

, cond_(lock_)

, shutdown_complete_(false)

, shutdown_signal_(0)

, dispatch_cleanup_delay_(30,0)

{

  try {

    this->init();

  } catch (...) {

    this->finalize();

    throw;

  }

}

  1. create_participant流程分析
    1. BUILTIN EntityID

/// Entity Id values specified in Version 2.1 of RTPS specification.

const EntityId_t ENTITYID_UNKNOWN                                = { {0x00,0x00,0x00}, 0x00};

const EntityId_t ENTITYID_PARTICIPANT                            = { {0x00,0x00,0x01}, 0xc1};

const EntityId_t ENTITYID_SEDP_BUILTIN_TOPIC_WRITER              = { {0x00,0x00,0x02}, 0xc2};

const EntityId_t ENTITYID_SEDP_BUILTIN_TOPIC_READER              = { {0x00,0x00,0x02}, 0xc7};

const EntityId_t ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER       = { {0x00,0x00,0x03}, 0xc2};

const EntityId_t ENTITYID_SEDP_BUILTIN_PUBLICATIONS_READER       = { {0x00,0x00,0x03}, 0xc7};

const EntityId_t ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER      = { {0x00,0x00,0x04}, 0xc2};

const EntityId_t ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_READER      = { {0x00,0x00,0x04}, 0xc7};

const EntityId_t ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER        = { {0x00,0x01,0x00}, 0xc2};

const EntityId_t ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER        = { {0x00,0x01,0x00}, 0xc7};

const EntityId_t ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER = { {0x00,0x02,0x00}, 0xc2};

const EntityId_t ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER = { {0x00,0x02,0x00}, 0xc7};

    1. BUILT_IN_TOPIC

const char* const BUILT_IN_PARTICIPANT_TOPIC = "DCPSParticipant";

const char* const BUILT_IN_PARTICIPANT_TOPIC_TYPE = "PARTICIPANT_BUILT_IN_TOPIC_TYPE";

const char* const BUILT_IN_TOPIC_TOPIC = "DCPSTopic";

const char* const BUILT_IN_TOPIC_TOPIC_TYPE = "TOPIC_BUILT_IN_TOPIC_TYPE";

const char* const BUILT_IN_SUBSCRIPTION_TOPIC = "DCPSSubscription";

const char* const BUILT_IN_SUBSCRIPTION_TOPIC_TYPE = "SUBSCRIPTION_BUILT_IN_TOPIC_TYPE";

const char* const BUILT_IN_PUBLICATION_TOPIC = "DCPSPublication";

const char* const BUILT_IN_PUBLICATION_TOPIC_TYPE = "PUBLICATION_BUILT_IN_TOPIC_TYPE";

const char* const BUILT_IN_PARTICIPANT_LOCATION_TOPIC = "OpenDDSParticipantLocation";

const char* const BUILT_IN_PARTICIPANT_LOCATION_TOPIC_TYPE = "PARTICIPANT_LOCATION_BUILT_IN_TOPIC_TYPE";

const char* const BUILT_IN_CONNECTION_RECORD_TOPIC = "OpenDDSConnectionRecord";

const char* const BUILT_IN_CONNECTION_RECORD_TOPIC_TYPE = "CONNECTION_RECORD_BUILT_IN_TOPIC_TYPE";

const char* const BUILT_IN_INTERNAL_THREAD_TOPIC = "OpenDDSInternalThread";

const char* const BUILT_IN_INTERNAL_THREAD_TOPIC_TYPE = "INTERNAL_THREAD_BUILT_IN_TOPIC_TYPE";

    1. DomainParticipantFactoryImpl::create_participant

DDS::DomainParticipant_ptr

DomainParticipantFactoryImpl::create_participant(

  DDS::DomainId_t domainId,

  const DDS::DomainParticipantQos & qos,

  DDS::DomainParticipantListener_ptr a_listener,

  DDS::StatusMask mask)

{

  DDS::DomainParticipantQos par_qos = qos;

  if (par_qos == PARTICIPANT_QOS_DEFAULT) {

    get_default_participant_qos(par_qos);

  }

  if (!Qos_Helper::valid(par_qos)) {

    if (DCPS_debug_level > 0) {

      ACE_ERROR((LM_ERROR,

                ACE_TEXT("(%P|%t) ERROR: ")

                ACE_TEXT("DomainParticipantFactoryImpl::create_participant, ")

                ACE_TEXT("invalid qos.\n")));

    }

    return DDS::DomainParticipant::_nil();

  }

  if (!Qos_Helper::consistent(par_qos)) {

    if (DCPS_debug_level > 0) {

      ACE_ERROR((LM_ERROR,

                ACE_TEXT("(%P|%t) ERROR: ")

                ACE_TEXT("DomainParticipantFactoryImpl::create_participant, ")

                ACE_TEXT("inconsistent qos.\n")));

    }

    return DDS::DomainParticipant::_nil();

  }

  RcHandle<DomainParticipantImpl> dp =

    make_rch<DomainParticipantImpl>(ref(participant_handles_), domainId, par_qos, a_listener, mask);

  if (qos_.entity_factory.autoenable_created_entities) {

    if (dp->enable() != DDS::RETCODE_OK) {

      if (DCPS_debug_level > 0) {

        ACE_ERROR((LM_ERROR,

                  ACE_TEXT("(%P|%t) ERROR: ")

                  ACE_TEXT("DomainParticipantFactoryImpl::create_participant, ")

                  ACE_TEXT("unable to enable DomainParticipant.\n")));

      }

      return DDS::DomainParticipant::_nil();

    }

  }

  // if the specified transport is a transport template then create a new transport

  // instance for the new participant if per_participant is set (checked before creating instance).

  ACE_TString transport_base_config_name;

  TheServiceParticipant->get_transport_base_config_name(domainId, transport_base_config_name);

  if (TheTransportRegistry->config_has_transport_template(transport_base_config_name)) {

    OPENDDS_STRING transport_config_name = ACE_TEXT_ALWAYS_CHAR(transport_base_config_name.c_str());

    OPENDDS_STRING transport_instance_name = dp->get_unique_id();

    // unique config and instance names are returned in transport_config_name and transport_instance_name

    const bool ret = TheTransportRegistry->create_new_transport_instance_for_participant(domainId, transport_config_name, transport_instance_name);

    if (ret) {

      TheTransportRegistry->bind_config(transport_config_name, dp.in());

      TheTransportRegistry->update_config_template_instance_info(transport_config_name, transport_instance_name);

    } else {

      if (DCPS_debug_level > 0) {

        ACE_ERROR((LM_ERROR,

                  ACE_TEXT("(%P|%t) ERROR: ")

                  ACE_TEXT("DomainParticipantFactoryImpl::create_participant, ")

                  ACE_TEXT("could not create new transport instance for participant.\n")));

      }

      return DDS::DomainParticipant::_nil();

    }

  }

  ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex,

                   guard,

                   participants_protector_,

                   DDS::DomainParticipant::_nil());

  participants_[domainId].insert(dp);

  return dp._retn();

}

    1. DomainParticipantImpl::enable

DDS::ReturnCode_t

DomainParticipantImpl::enable()

{

  //According spec:

  // - Calling enable on an already enabled Entity returns OK and has no

  // effect.

  // - Calling enable on an Entity whose factory is not enabled will fail

  // and return PRECONDITION_NOT_MET.

  if (this->is_enabled()) {

    return DDS::RETCODE_OK;

  }

#ifdef OPENDDS_SECURITY

  if (!security_config_ && TheServiceParticipant->get_security()) {

    security_config_ = TheSecurityRegistry->default_config();

    if (!security_config_) {

      security_config_ = TheSecurityRegistry->builtin_config();

      TheSecurityRegistry->default_config(security_config_);

    }

  }

#endif

  Discovery_rch disco = TheServiceParticipant->get_discovery(domain_id_);

  if (disco.is_nil()) {

    if (DCPS_debug_level > 0) {

      ACE_ERROR((LM_ERROR,

                ACE_TEXT("(%P|%t) ERROR: DomainParticipantImpl::enable, ")

                ACE_TEXT("no discovery found for domain id: %d.\n"), domain_id_));

    }

    return DDS::RETCODE_ERROR;

  }

#ifdef OPENDDS_SECURITY

  if (TheServiceParticipant->get_security() && !security_config_) {

    if (DCPS::security_debug.new_entity_error) {

      ACE_ERROR((LM_ERROR,

                 ACE_TEXT("(%P|%t) ERROR: DomainParticipantImpl::enable, ")

                 ACE_TEXT("DCPSSecurity flag is set, but unable to load security plugin configuration.\n")));

    }

    return DDS::RETCODE_ERROR;

  }

#endif

  AddDomainStatus value = {GUID_UNKNOWN, false};

#ifdef OPENDDS_SECURITY

  if (TheServiceParticipant->get_security() && security_config_->qos_implies_security(qos_)) {

    Security::Authentication_var auth = security_config_->get_authentication();

    DDS::Security::SecurityException se;

    DDS::Security::ValidationResult_t val_res =

      auth->validate_local_identity(id_handle_, dp_id_, domain_id_, qos_, disco->generate_participant_guid(), se);

    /* TODO - Handle VALIDATION_PENDING_RETRY */

    if (val_res != DDS::Security::VALIDATION_OK) {

      if (DCPS::security_debug.new_entity_error) {

        ACE_ERROR((LM_ERROR,

                   ACE_TEXT("(%P|%t) ERROR: DomainParticipantImpl::enable, ")

                   ACE_TEXT("Unable to validate local identity. SecurityException[%d.%d]: %C\n"),

                   se.code, se.minor_code, se.message.in()));

      }

      return DDS::Security::RETCODE_NOT_ALLOWED_BY_SECURITY;

    }

    Security::AccessControl_var access = security_config_->get_access_control();

    perm_handle_ = access->validate_local_permissions(auth, id_handle_, domain_id_, qos_, se);

    if (perm_handle_ == DDS::HANDLE_NIL) {

      if (DCPS::security_debug.new_entity_error) {

        ACE_ERROR((LM_ERROR,

                   ACE_TEXT("(%P|%t) ERROR: DomainParticipantImpl::enable, ")

                   ACE_TEXT("Unable to validate local permissions. SecurityException[%d.%d]: %C\n"),

                   se.code, se.minor_code, se.message.in()));

      }

      return DDS::Security::RETCODE_NOT_ALLOWED_BY_SECURITY;

    }

    const bool check_create = access->check_create_participant(perm_handle_, domain_id_, qos_, se);

    if (!check_create) {

      if (DCPS::security_debug.new_entity_error) {

        ACE_ERROR((LM_ERROR,

                   ACE_TEXT("(%P|%t) ERROR: DomainParticipantImpl::enable, ")

                   ACE_TEXT("Unable to create participant. SecurityException[%d.%d]: %C\n"),

                   se.code, se.minor_code, se.message.in()));

      }

      return DDS::Security::RETCODE_NOT_ALLOWED_BY_SECURITY;

    }

    DDS::Security::ParticipantSecurityAttributes part_sec_attr;

    const bool check_part_sec_attr = access->get_participant_sec_attributes(perm_handle_, part_sec_attr, se);

    if (!check_part_sec_attr) {

      if (DCPS::security_debug.new_entity_error) {

        ACE_ERROR((LM_ERROR,

                   ACE_TEXT("(%P|%t) ERROR: DomainParticipantImpl::enable,")

                   ACE_TEXT("Unable to get participant security attributes. SecurityException[%d.%d]: %C\n"),

                   se.code, se.minor_code, se.message.in()));

      }

      return DDS::RETCODE_ERROR;

    }

    if (part_sec_attr.is_rtps_protected) { // DDS-Security v1.1 8.4.2.4 Table 27 is_rtps_protected

      if (part_sec_attr.allow_unauthenticated_participants) {

        if (DCPS::security_debug.new_entity_error) {

          ACE_ERROR((LM_ERROR,

                     ACE_TEXT("(%P|%t) ERROR: DomainParticipantImpl::enable, ")

                     ACE_TEXT("allow_unauthenticated_participants is not possible with is_rtps_protected\n")));

        }

        return DDS::Security::RETCODE_NOT_ALLOWED_BY_SECURITY;

      }

      const Security::CryptoKeyFactory_var crypto = security_config_->get_crypto_key_factory();

      part_crypto_handle_ = crypto->register_local_participant(id_handle_, perm_handle_,

        Util::filter_properties(qos_.property.value, "dds.sec.crypto."), part_sec_attr, se);

      if (part_crypto_handle_ == DDS::HANDLE_NIL) {

        if (DCPS::security_debug.new_entity_error) {

          ACE_ERROR((LM_ERROR,

                     ACE_TEXT("(%P|%t) ERROR: DomainParticipantImpl::enable, ")

                     ACE_TEXT("Unable to register local participant. SecurityException[%d.%d]: %C\n"),

                     se.code, se.minor_code, se.message.in()));

        }

        return DDS::RETCODE_ERROR;

      }

    } else {

      part_crypto_handle_ = DDS::HANDLE_NIL;

    }

    value = disco->add_domain_participant_secure(domain_id_, qos_, type_lookup_service_,

                                                 dp_id_, id_handle_, perm_handle_, part_crypto_handle_);

    if (value.id == GUID_UNKNOWN) {

      if (DCPS::security_debug.new_entity_error) {

        ACE_ERROR((LM_ERROR,

                   ACE_TEXT("(%P|%t) ERROR: DomainParticipantImpl::enable, ")

                   ACE_TEXT("add_domain_participant_secure returned invalid id.\n")));

      }

      return DDS::RETCODE_ERROR;

    }

  } else {

#endif

    value = disco->add_domain_participant(domain_id_, qos_, type_lookup_service_);

    if (value.id == GUID_UNKNOWN) {

      if (DCPS_debug_level > 0) {

        ACE_ERROR((LM_ERROR,

                   ACE_TEXT("(%P|%t) ERROR: DomainParticipantImpl::enable, ")

                   ACE_TEXT("add_domain_participant returned invalid id.\n")));

      }

      return DDS::RETCODE_ERROR;

    }

#ifdef OPENDDS_SECURITY

  }

#endif

  dp_id_ = value.id;

  federated_ = value.federated;

  if (monitor_) {

    monitor_->report();

  }

  if (TheServiceParticipant->monitor_) {

    TheServiceParticipant->monitor_->report();

  }

  const DDS::ReturnCode_t ret = this->set_enabled();

  if (DCPS_debug_level > 1) {

    ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DomainParticipantImpl::enable: ")

               ACE_TEXT("enabled participant %C in domain %d\n"),

               LogGuid(dp_id_).c_str(), domain_id_));

  }

  if (ret == DDS::RETCODE_OK && !TheTransientKludge->is_enabled()) {

    Discovery_rch disc = TheServiceParticipant->get_discovery(this->domain_id_);

    this->bit_subscriber_ = disc->init_bit(this);

  }

  if (ret != DDS::RETCODE_OK) {

    return ret;

  }

  if (qos_.entity_factory.autoenable_created_entities) {

    for (TopicMap::iterator it = topics_.begin(); it != topics_.end(); ++it) {

      it->second.pair_.svt_->enable();

    }

    for (PublisherSet::iterator it = publishers_.begin(); it != publishers_.end(); ++it) {

      it->svt_->enable();

    }

    for (SubscriberSet::iterator it = subscribers_.begin(); it != subscribers_.end(); ++it) {

      it->svt_->enable();

    }

  }

  return DDS::RETCODE_OK;

}

    1. RtpsDiscovery::add_domain_participant

DCPS::AddDomainStatus

RtpsDiscovery::add_domain_participant(DDS::DomainId_t domain,

                                      const DDS::DomainParticipantQos& qos,

                                      XTypes::TypeLookupService_rch tls)

{

  DCPS::AddDomainStatus ads = {OpenDDS::DCPS::RepoId(), false /*federated*/};

  {

    ACE_GUARD_RETURN(ACE_Thread_Mutex, g, lock_, ads);

    const OPENDDS_STRING guid_interface = config_->guid_interface();

    if (!guid_interface.empty()) {

      if (guid_gen_.interfaceName(guid_interface.c_str()) != 0) {

        if (DCPS::DCPS_debug_level) {

          ACE_DEBUG((LM_WARNING, "(%P|%t) RtpsDiscovery::add_domain_participant()"

                     " - attempt to use specific network interface %C MAC addr for"

                     " GUID generation failed.\n", guid_interface.c_str()));

        }

      }

    }

    guid_gen_.populate(ads.id);

  }

  ads.id.entityId = ENTITYID_PARTICIPANT;

  try {

    const DCPS::RcHandle<Spdp> spdp(DCPS::make_rch<Spdp>(domain, ref(ads.id), qos, this, tls));

    // ads.id may change during Spdp constructor

    ACE_GUARD_RETURN(ACE_Thread_Mutex, g, participants_lock_, ads);

    participants_[domain][ads.id] = spdp;

  } catch (const std::exception& e) {

    ads.id = GUID_UNKNOWN;

    ACE_ERROR((LM_ERROR, "(%P|%t) RtpsDiscovery::add_domain_participant() - "

      "failed to initialize RTPS Simple Participant Discovery Protocol: %C\n",

      e.what()));

  }

  return ads;

}

    1. SPDP
      1. Spdp::Spdp

Spdp::Spdp(DDS::DomainId_t domain,

           RepoId& guid,

           const DDS::DomainParticipantQos& qos,

           RtpsDiscovery* disco,

           XTypes::TypeLookupService_rch tls)

  : qos_(qos)

  , disco_(disco)

  , config_(disco_->config())

  , lease_duration_(disco_->config()->lease_duration())

  , lease_extension_(disco_->config()->lease_extension())

  , domain_(domain)

  , guid_(guid)

  , participant_discovered_at_(MonotonicTimePoint::now().to_monotonic_time())

  , is_application_participant_(false)

  , tport_(DCPS::make_rch<SpdpTransport>(rchandle_from(this)))

  , initialized_flag_(false)

  , eh_shutdown_(false)

  , shutdown_cond_(lock_)

  , shutdown_flag_(false)

  , available_builtin_endpoints_(0)

  , sedp_(DCPS::make_rch<Sedp>(guid_, DCPS::ref(*this), DCPS::ref(lock_)))

#ifdef OPENDDS_SECURITY

  , available_extended_builtin_endpoints_(0)

  , security_config_()

  , security_enabled_(false)

  , identity

  • 20
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值