Coverage Report

Created: 2026-04-01 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/Fast-DDS/src/cpp/fastdds/domain/DomainParticipantImpl.cpp
Line
Count
Source
1
// Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
/**
16
 * @file DomainParticipantImpl.cpp
17
 *
18
 */
19
20
#include <fastdds/domain/DomainParticipantImpl.hpp>
21
22
#include <algorithm>
23
#include <chrono>
24
#include <string>
25
26
#include "../../rtps/network/asio.hpp"
27
28
#include <fastdds/core/policy/QosPolicyUtils.hpp>
29
#include <fastdds/dds/builtin/topic/ParticipantBuiltinTopicData.hpp>
30
#include <fastdds/dds/core/ReturnCode.hpp>
31
#include <fastdds/dds/domain/DomainParticipant.hpp>
32
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
33
#include <fastdds/dds/domain/DomainParticipantListener.hpp>
34
#include <fastdds/dds/log/Log.hpp>
35
#include <fastdds/dds/publisher/DataWriter.hpp>
36
#include <fastdds/dds/publisher/Publisher.hpp>
37
#include <fastdds/dds/subscriber/DataReader.hpp>
38
#include <fastdds/dds/subscriber/Subscriber.hpp>
39
#include <fastdds/dds/topic/IContentFilterFactory.hpp>
40
#include <fastdds/dds/topic/TypeSupport.hpp>
41
#include <fastdds/dds/xtypes/dynamic_types/DynamicPubSubType.hpp>
42
#include <fastdds/dds/xtypes/dynamic_types/DynamicType.hpp>
43
#include <fastdds/rtps/attributes/PropertyPolicy.hpp>
44
#include <fastdds/rtps/attributes/RTPSParticipantAttributes.hpp>
45
#include <fastdds/rtps/common/Guid.hpp>
46
#include <fastdds/rtps/common/GuidPrefix_t.hpp>
47
#include <fastdds/rtps/participant/ParticipantDiscoveryInfo.hpp>
48
#include <fastdds/rtps/participant/RTPSParticipant.hpp>
49
#include <fastdds/rtps/reader/ReaderDiscoveryStatus.hpp>
50
#include <fastdds/rtps/RTPSDomain.hpp>
51
#include <fastdds/rtps/writer/WriterDiscoveryStatus.hpp>
52
53
#include <fastdds/builtin/type_lookup_service/TypeLookupManager.hpp>
54
#include <fastdds/publisher/DataWriterImpl.hpp>
55
#include <fastdds/publisher/PublisherImpl.hpp>
56
#include <fastdds/subscriber/SubscriberImpl.hpp>
57
#include <fastdds/topic/ContentFilteredTopicImpl.hpp>
58
#include <fastdds/topic/DDSSQLFilter/DDSFilterFactory.hpp>
59
#include <fastdds/topic/TopicImpl.hpp>
60
#include <fastdds/topic/TopicProxy.hpp>
61
#include <fastdds/topic/TopicProxyFactory.hpp>
62
#include <fastdds/utils/QosConverters.hpp>
63
#include <fastdds/utils/TypePropagation.hpp>
64
#include <rtps/builtin/liveliness/WLP.hpp>
65
#include <rtps/domain/RTPSDomainImpl.hpp>
66
#include <utils/SystemInfo.hpp>
67
#include <xmlparser/attributes/PublisherAttributes.hpp>
68
#include <xmlparser/attributes/ReplierAttributes.hpp>
69
#include <xmlparser/attributes/RequesterAttributes.hpp>
70
#include <xmlparser/attributes/SubscriberAttributes.hpp>
71
#include <xmlparser/attributes/TopicAttributes.hpp>
72
#include <xmlparser/XMLProfileManager.h>
73
74
namespace eprosima {
75
namespace fastdds {
76
namespace dds {
77
78
using xmlparser::XMLProfileManager;
79
using xmlparser::XMLP_ret;
80
using rtps::RTPSDomain;
81
using rtps::RTPSDomainImpl;
82
using rtps::RTPSParticipant;
83
using xmlparser::XMLP_ret;
84
using xmlparser::XMLProfileManager;
85
#if HAVE_SECURITY
86
using rtps::ParticipantAuthenticationInfo;
87
#endif // if HAVE_SECURITY
88
using rtps::EndpointKind_t;
89
using rtps::ReaderDiscoveryStatus;
90
using rtps::ResourceEvent;
91
using rtps::WriterDiscoveryStatus;
92
93
static size_t get_filter_max_subexpressions(
94
        const DomainParticipantQos& qos)
95
0
{
96
0
    constexpr const char parameter_name[] = "dds.sql.expression.max_subexpressions";
97
0
    const std::string* property = fastdds::rtps::PropertyPolicyHelper::find_property(
98
0
        qos.properties(), parameter_name);
99
0
    if (nullptr != property)
100
0
    {
101
0
        try
102
0
        {
103
0
            return std::stoul(*property);
104
0
        }
105
0
        catch (...)
106
0
        {
107
0
            EPROSIMA_LOG_WARNING(DOMAIN_PARTICIPANT,
108
0
                    "Invalid value for dds.sql.expression.max_subexpressions property: "
109
0
                    << *property << ". Will use default value of "
110
0
                    << DDSSQLFilter::DDSFilterFactory::DEFAULT_MAX_SUBEXPRESSIONS);
111
0
        }
112
0
    }
113
114
0
    return DDSSQLFilter::DDSFilterFactory::DEFAULT_MAX_SUBEXPRESSIONS;
115
0
}
116
117
static size_t get_filter_max_expression_length(
118
        const DomainParticipantQos& qos)
119
0
{
120
0
    constexpr const char parameter_name[] = "dds.sql.expression.max_expression_length";
121
0
    const std::string* property = fastdds::rtps::PropertyPolicyHelper::find_property(
122
0
        qos.properties(), parameter_name);
123
0
    if (nullptr != property)
124
0
    {
125
0
        try
126
0
        {
127
0
            return std::stoul(*property);
128
0
        }
129
0
        catch (...)
130
0
        {
131
0
            EPROSIMA_LOG_WARNING(DOMAIN_PARTICIPANT,
132
0
                    "Invalid value for dds.sql.expression.max_expression_length property: "
133
0
                    << *property << ". Will use default value of "
134
0
                    << DDSSQLFilter::DDSFilterFactory::DEFAULT_MAX_EXPRESSION_LENGTH);
135
0
        }
136
0
    }
137
138
0
    return DDSSQLFilter::DDSFilterFactory::DEFAULT_MAX_EXPRESSION_LENGTH;
139
0
}
140
141
DomainParticipantImpl::DomainParticipantImpl(
142
        DomainParticipant* dp,
143
        DomainId_t did,
144
        const DomainParticipantQos& qos,
145
        DomainParticipantListener* listen)
146
0
    : domain_id_(did)
147
0
    , next_instance_id_(0)
148
0
    , qos_(qos)
149
0
    , rtps_participant_(nullptr)
150
0
    , participant_(dp)
151
0
    , listener_(listen)
152
0
    , default_pub_qos_(PUBLISHER_QOS_DEFAULT)
153
0
    , default_sub_qos_(SUBSCRIBER_QOS_DEFAULT)
154
0
    , dds_sql_filter_factory_(get_filter_max_subexpressions(qos), get_filter_max_expression_length(qos))
155
0
    , default_topic_qos_(TOPIC_QOS_DEFAULT)
156
0
    , id_counter_(0)
157
#pragma warning (disable : 4355 )
158
0
    , rtps_listener_(this)
159
0
{
160
0
    participant_->impl_ = this;
161
162
0
    xmlparser::PublisherAttributes pub_attr;
163
0
    XMLProfileManager::getDefaultPublisherAttributes(pub_attr);
164
0
    utils::set_qos_from_attributes(default_pub_qos_, pub_attr);
165
166
0
    xmlparser::SubscriberAttributes sub_attr;
167
0
    XMLProfileManager::getDefaultSubscriberAttributes(sub_attr);
168
0
    utils::set_qos_from_attributes(default_sub_qos_, sub_attr);
169
170
0
    xmlparser::TopicAttributes top_attr;
171
0
    XMLProfileManager::getDefaultTopicAttributes(top_attr);
172
0
    utils::set_qos_from_attributes(default_topic_qos_, top_attr);
173
174
    // Pre calculate participant id and generated guid
175
0
    participant_id_ = qos_.wire_protocol().participant_id;
176
0
    if (!eprosima::fastdds::rtps::RTPSDomainImpl::get_instance()->create_participant_guid(participant_id_, guid_))
177
0
    {
178
0
        EPROSIMA_LOG_ERROR(DOMAIN_PARTICIPANT, "Error generating GUID for participant");
179
0
    }
180
0
    handle_ = guid_;
181
182
    /* Fill physical data properties if they are found and empty */
183
0
    std::string* property_value = fastdds::rtps::PropertyPolicyHelper::find_property(
184
0
        qos_.properties(), parameter_policy_physical_data_host);
185
0
    if (nullptr != property_value && property_value->empty())
186
0
    {
187
0
        if (SystemInfo::instance().machine_id().size() > 0)
188
0
        {
189
0
            property_value->assign(SystemInfo::instance().machine_id().to_string());
190
0
        }
191
0
        else
192
0
        {
193
0
            property_value->assign(asio::ip::host_name() + ":" + std::to_string(utils::default_domain_id()));
194
0
        }
195
0
    }
196
197
0
    property_value = fastdds::rtps::PropertyPolicyHelper::find_property(
198
0
        qos_.properties(), parameter_policy_physical_data_user);
199
0
    if (nullptr != property_value && property_value->empty())
200
0
    {
201
0
        std::string username = "unknown";
202
0
        if (RETCODE_OK == SystemInfo::get_username(username))
203
0
        {
204
0
            property_value->assign(username);
205
0
        }
206
0
    }
207
208
0
    property_value = fastdds::rtps::PropertyPolicyHelper::find_property(
209
0
        qos_.properties(), parameter_policy_physical_data_process);
210
0
    if (nullptr != property_value && property_value->empty())
211
0
    {
212
0
        property_value->assign(std::to_string(SystemInfo::instance().process_id()));
213
0
    }
214
0
}
215
216
void DomainParticipantImpl::disable()
217
0
{
218
0
    DomainParticipant* participant = get_participant();
219
0
    if (participant)
220
0
    {
221
0
        participant->set_listener(nullptr);
222
0
    }
223
224
    // The function to disable the DomainParticipantImpl is called from
225
    // DomainParticipantFactory::delete_participant() and DomainParticipantFactory destructor.
226
0
    auto rtps_participant = get_rtps_participant();
227
0
    if (rtps_participant != nullptr)
228
0
    {
229
0
        rtps_participant->set_listener(nullptr);
230
231
0
        {
232
0
            std::lock_guard<std::mutex> lock(mtx_pubs_);
233
0
            for (auto pub_it = publishers_.begin(); pub_it != publishers_.end(); ++pub_it)
234
0
            {
235
0
                pub_it->second->disable();
236
0
            }
237
0
        }
238
239
0
        {
240
0
            std::lock_guard<std::mutex> lock(mtx_subs_);
241
0
            for (auto sub_it = subscribers_.begin(); sub_it != subscribers_.end(); ++sub_it)
242
0
            {
243
0
                sub_it->second->disable();
244
0
            }
245
0
        }
246
0
    }
247
0
}
248
249
DomainParticipantImpl::~DomainParticipantImpl()
250
0
{
251
0
    {
252
0
        std::lock_guard<std::mutex> lock(mtx_pubs_);
253
0
        for (auto pub_it = publishers_.begin(); pub_it != publishers_.end(); ++pub_it)
254
0
        {
255
0
            delete pub_it->second;
256
0
        }
257
0
        publishers_.clear();
258
0
        publishers_by_handle_.clear();
259
0
    }
260
261
0
    {
262
0
        std::lock_guard<std::mutex> lock(mtx_subs_);
263
264
0
        for (auto sub_it = subscribers_.begin(); sub_it != subscribers_.end(); ++sub_it)
265
0
        {
266
0
            delete sub_it->second;
267
0
        }
268
0
        subscribers_.clear();
269
0
        subscribers_by_handle_.clear();
270
0
    }
271
272
0
    {
273
0
        std::lock_guard<std::mutex> lock(mtx_topics_);
274
275
0
        filtered_topics_.clear();
276
277
0
        for (auto topic_it = topics_.begin(); topic_it != topics_.end(); ++topic_it)
278
0
        {
279
0
            delete topic_it->second;
280
0
        }
281
0
        topics_.clear();
282
0
        topics_by_handle_.clear();
283
0
    }
284
285
0
    auto rtps_participant = get_rtps_participant();
286
0
    if (rtps_participant != nullptr)
287
0
    {
288
0
        RTPSDomain::removeRTPSParticipant(rtps_participant);
289
0
    }
290
291
0
    {
292
0
        std::lock_guard<std::mutex> lock(mtx_types_);
293
0
        types_.clear();
294
0
    }
295
296
0
    std::lock_guard<std::mutex> _(mtx_gs_);
297
298
    // Assert no callbacks are being executed.
299
    // Note that this should never occur since reception and events threads joined when removing rtps_participant.
300
0
    assert(!(rtps_listener_.callback_counter_ > 0));
301
302
0
    if (participant_)
303
0
    {
304
0
        participant_->impl_ = nullptr;
305
0
        delete participant_;
306
0
        participant_ = nullptr;
307
0
    }
308
0
}
309
310
ReturnCode_t DomainParticipantImpl::enable()
311
0
{
312
    // Should not have been previously enabled
313
0
    assert(get_rtps_participant() == nullptr);
314
    // Should not have failed assigning the GUID
315
0
    assert (guid_ != fastdds::rtps::GUID_t::unknown());
316
317
0
    auto qos_check = check_qos(qos_);
318
319
0
    if (RETCODE_OK != qos_check)
320
0
    {
321
0
        return qos_check;
322
0
    }
323
324
0
    fastdds::rtps::RTPSParticipantAttributes rtps_attr;
325
0
    utils::set_attributes_from_qos(rtps_attr, qos_);
326
0
    rtps_attr.participantID = participant_id_;
327
328
0
    RTPSParticipant* part = RTPSDomain::createParticipant(
329
0
        domain_id_,
330
0
        false,
331
0
        rtps_attr,
332
0
        &rtps_listener_);
333
334
0
    if (part == nullptr)
335
0
    {
336
0
        EPROSIMA_LOG_ERROR(DOMAIN_PARTICIPANT, "Problem creating RTPSParticipant");
337
0
        return RETCODE_ERROR;
338
0
    }
339
340
0
    guid_ = part->getGuid();
341
0
    handle_ = guid_;
342
343
0
    {
344
0
        std::lock_guard<std::mutex> _(mtx_gs_);
345
346
0
        rtps_participant_ = part;
347
348
0
        part->set_check_type_function(
349
0
            [this](const std::string& type_name) -> bool
350
0
            {
351
0
                return find_type(type_name).get() != nullptr;
352
0
            });
353
0
    }
354
355
0
    if (qos_.entity_factory().autoenable_created_entities)
356
0
    {
357
        // Enable topics first
358
0
        {
359
0
            std::lock_guard<std::mutex> lock(mtx_topics_);
360
361
0
            for (auto topic : topics_)
362
0
            {
363
0
                topic.second->enable_topic();
364
0
            }
365
0
        }
366
367
        // Enable publishers
368
0
        {
369
0
            std::lock_guard<std::mutex> lock(mtx_pubs_);
370
0
            for (auto pub : publishers_)
371
0
            {
372
0
                pub.second->rtps_participant_ = part;
373
0
                pub.second->user_publisher_->enable();
374
0
            }
375
0
        }
376
377
        // Enable subscribers
378
0
        {
379
0
            std::lock_guard<std::mutex> lock(mtx_subs_);
380
381
0
            for (auto sub : subscribers_)
382
0
            {
383
0
                sub.second->rtps_participant_ = part;
384
0
                sub.second->user_subscriber_->enable();
385
0
            }
386
0
        }
387
0
    }
388
389
0
    part->enable();
390
391
0
    return RETCODE_OK;
392
0
}
393
394
ReturnCode_t DomainParticipantImpl::set_qos(
395
        const DomainParticipantQos& qos)
396
0
{
397
0
    bool enabled = false;
398
0
    bool qos_should_be_updated = false;
399
0
    fastdds::rtps::RTPSParticipantAttributes patt;
400
0
    fastdds::rtps::RTPSParticipant* rtps_participant = nullptr;
401
402
0
    {
403
0
        std::lock_guard<std::mutex> _(mtx_gs_);
404
405
0
        rtps_participant = rtps_participant_;
406
0
        enabled = rtps_participant != nullptr;
407
0
        const DomainParticipantQos& qos_to_set = (&qos == &PARTICIPANT_QOS_DEFAULT) ?
408
0
                DomainParticipantFactory::get_instance()->get_default_participant_qos() : qos;
409
410
0
        if (&qos != &PARTICIPANT_QOS_DEFAULT)
411
0
        {
412
0
            ReturnCode_t ret_val = check_qos(qos_to_set);
413
0
            if (RETCODE_OK != ret_val)
414
0
            {
415
0
                return ret_val;
416
0
            }
417
0
        }
418
419
0
        if (enabled && !can_qos_be_updated(qos_, qos_to_set))
420
0
        {
421
0
            return RETCODE_IMMUTABLE_POLICY;
422
0
        }
423
424
0
        qos_should_be_updated = set_qos(qos_, qos_to_set, !enabled);
425
0
        if (enabled)
426
0
        {
427
0
            if (qos_should_be_updated)
428
0
            {
429
                // Notify the participant that there is a QoS update
430
0
                utils::set_attributes_from_qos(patt, qos_);
431
0
            }
432
0
            else
433
0
            {
434
                // Trigger update of network interfaces by calling update_attributes with current attributes
435
0
                patt = rtps_participant->get_attributes();
436
0
            }
437
0
        }
438
0
    }
439
440
0
    if (enabled)
441
0
    {
442
0
        rtps_participant->update_attributes(patt);
443
0
    }
444
445
0
    return RETCODE_OK;
446
0
}
447
448
ReturnCode_t DomainParticipantImpl::get_qos(
449
        DomainParticipantQos& qos) const
450
0
{
451
0
    std::lock_guard<std::mutex> _(mtx_gs_);
452
0
    qos = qos_;
453
0
    return RETCODE_OK;
454
0
}
455
456
const DomainParticipantQos& DomainParticipantImpl::get_qos() const
457
0
{
458
0
    std::lock_guard<std::mutex> _(mtx_gs_);
459
0
    return qos_;
460
0
}
461
462
ReturnCode_t DomainParticipantImpl::delete_publisher(
463
        const Publisher* pub)
464
0
{
465
0
    if (get_participant() != pub->get_participant())
466
0
    {
467
0
        return RETCODE_PRECONDITION_NOT_MET;
468
0
    }
469
0
    std::lock_guard<std::mutex> lock(mtx_pubs_);
470
0
    auto pit = publishers_.find(const_cast<Publisher*>(pub));
471
472
0
    if (pit != publishers_.end())
473
0
    {
474
0
        assert(pub->get_instance_handle() == pit->second->get_instance_handle()
475
0
                && "The publisher instance handle does not match the publisher implementation instance handle");
476
0
        if (pub->has_datawriters())
477
0
        {
478
0
            return RETCODE_PRECONDITION_NOT_MET;
479
0
        }
480
0
        pit->second->set_listener(nullptr);
481
0
        publishers_by_handle_.erase(publishers_by_handle_.find(pit->second->get_instance_handle()));
482
0
        delete pit->second;
483
0
        publishers_.erase(pit);
484
0
        return RETCODE_OK;
485
0
    }
486
487
0
    return RETCODE_ERROR;
488
0
}
489
490
ReturnCode_t DomainParticipantImpl::delete_subscriber(
491
        const Subscriber* sub)
492
0
{
493
0
    if (get_participant() != sub->get_participant())
494
0
    {
495
0
        return RETCODE_PRECONDITION_NOT_MET;
496
0
    }
497
0
    std::lock_guard<std::mutex> lock(mtx_subs_);
498
0
    auto sit = subscribers_.find(const_cast<Subscriber*>(sub));
499
500
0
    if (sit != subscribers_.end())
501
0
    {
502
0
        assert(sub->get_instance_handle() == sit->second->get_instance_handle()
503
0
                && "The subscriber instance handle does not match the subscriber implementation instance handle");
504
0
        if (sub->has_datareaders())
505
0
        {
506
0
            return RETCODE_PRECONDITION_NOT_MET;
507
0
        }
508
0
        sit->second->set_listener(nullptr);
509
0
        subscribers_by_handle_.erase(subscribers_by_handle_.find(sit->second->get_instance_handle()));
510
0
        delete sit->second;
511
0
        subscribers_.erase(sit);
512
0
        return RETCODE_OK;
513
0
    }
514
515
0
    return RETCODE_ERROR;
516
0
}
517
518
Topic* DomainParticipantImpl::find_topic(
519
        const std::string& topic_name,
520
        const fastdds::dds::Duration_t& timeout)
521
0
{
522
0
    auto find_fn = [this, &topic_name]()
523
0
            {
524
0
                return topics_.count(topic_name) > 0;
525
0
            };
526
527
0
    std::unique_lock<std::mutex> lock(mtx_topics_);
528
0
    if (timeout.is_infinite())
529
0
    {
530
0
        cond_topics_.wait(lock, find_fn);
531
0
    }
532
0
    else
533
0
    {
534
0
        auto duration = std::chrono::seconds(timeout.seconds) + std::chrono::nanoseconds(timeout.nanosec);
535
0
        if (!cond_topics_.wait_for(lock, duration, find_fn))
536
0
        {
537
0
            return nullptr;
538
0
        }
539
0
    }
540
541
0
    Topic* ret_val = topics_[topic_name]->create_topic()->get_topic();
542
543
0
    InstanceHandle_t topic_handle;
544
0
    create_instance_handle(topic_handle);
545
0
    ret_val->set_instance_handle(topic_handle);
546
0
    topics_by_handle_[topic_handle] = ret_val;
547
548
0
    return ret_val;
549
0
}
550
551
void DomainParticipantImpl::set_topic_listener(
552
        const TopicProxyFactory* factory,
553
        TopicImpl* impl,
554
        TopicListener* listener,
555
        const StatusMask& mask)
556
0
{
557
0
    std::lock_guard<std::mutex> lock(mtx_topics_);
558
0
    impl->set_listener(listener);
559
0
    factory->for_each([mask](const std::unique_ptr<TopicProxy>& proxy)
560
0
            {
561
0
                proxy->get_topic()->status_mask_ = mask;
562
0
            });
563
0
}
564
565
ReturnCode_t DomainParticipantImpl::delete_topic(
566
        const Topic* topic)
567
0
{
568
0
    if (topic == nullptr)
569
0
    {
570
0
        return RETCODE_BAD_PARAMETER;
571
0
    }
572
573
0
    std::lock_guard<std::mutex> lock(mtx_topics_);
574
0
    auto handle_it = std::find_if(topics_by_handle_.begin(), topics_by_handle_.end(),
575
0
                    [topic](const decltype(topics_by_handle_)::value_type& item)
576
0
                    {
577
0
                        return item.second == topic;
578
0
                    });
579
0
    if (handle_it != topics_by_handle_.end())
580
0
    {
581
0
        auto it = topics_.find(topic->get_name());
582
0
        assert(it != topics_.end() && "Topic found by handle but factory not found");
583
0
        InstanceHandle_t handle = topic->get_instance_handle();
584
585
0
        TopicProxy* proxy = dynamic_cast<TopicProxy*>(topic->get_impl());
586
0
        assert(nullptr != proxy);
587
0
        auto ret_code = it->second->delete_topic(proxy);
588
0
        if (RETCODE_OK == ret_code)
589
0
        {
590
0
            topics_by_handle_.erase(handle);
591
592
0
            if (it->second->can_be_deleted())
593
0
            {
594
0
                auto factory = it->second;
595
0
                topics_.erase(it);
596
0
                delete factory;
597
0
            }
598
0
        }
599
0
        return ret_code;
600
0
    }
601
602
0
    return RETCODE_PRECONDITION_NOT_MET;
603
0
}
604
605
ContentFilteredTopic* DomainParticipantImpl::create_contentfilteredtopic(
606
        const std::string& name,
607
        Topic* related_topic,
608
        const std::string& filter_expression,
609
        const std::vector<std::string>& expression_parameters,
610
        const char* filter_class_name,
611
        ReturnCode_t& ret_code)
612
0
{
613
0
    ContentFilteredTopic* topic = create_contentfilteredtopic(name, related_topic, filter_expression,
614
0
                    expression_parameters, filter_class_name);
615
0
    ret_code = (topic != nullptr) ? RETCODE_OK : RETCODE_ERROR;
616
0
    return topic;
617
0
}
618
619
ContentFilteredTopic* DomainParticipantImpl::create_contentfilteredtopic(
620
        const std::string& name,
621
        Topic* related_topic,
622
        const std::string& filter_expression,
623
        const std::vector<std::string>& expression_parameters,
624
        const char* filter_class_name)
625
0
{
626
0
    if ((nullptr == related_topic) || (nullptr == filter_class_name))
627
0
    {
628
0
        return nullptr;
629
0
    }
630
631
0
    std::lock_guard<std::mutex> lock(mtx_topics_);
632
633
    // Check there is no Topic with the same name
634
0
    if ((topics_.find(name) != topics_.end()) ||
635
0
            (filtered_topics_.find(name) != filtered_topics_.end()))
636
0
    {
637
0
        EPROSIMA_LOG_ERROR(PARTICIPANT, "Topic with name : " << name << " already exists");
638
0
        return nullptr;
639
0
    }
640
641
0
    if (related_topic->get_participant() != get_participant())
642
0
    {
643
0
        EPROSIMA_LOG_ERROR(PARTICIPANT, "Creating ContentFilteredTopic with name " << name
644
0
                                                                                   <<
645
0
                ": related_topic not from this participant");
646
0
        return nullptr;
647
0
    }
648
649
0
    IContentFilterFactory* filter_factory = find_content_filter_factory(filter_class_name);
650
0
    if (nullptr == filter_factory)
651
0
    {
652
0
        EPROSIMA_LOG_ERROR(PARTICIPANT, "Could not find factory for filter class " << filter_class_name);
653
0
        return nullptr;
654
0
    }
655
656
0
    if (expression_parameters.size() > qos_.allocation().content_filter.expression_parameters.maximum)
657
0
    {
658
0
        EPROSIMA_LOG_ERROR(PARTICIPANT, "Number of expression parameters exceeds maximum allocation limit: "
659
0
                << expression_parameters.size() << " > "
660
0
                << qos_.allocation().content_filter.expression_parameters.maximum);
661
0
        return nullptr;
662
0
    }
663
664
0
    if (expression_parameters.size() > 100)
665
0
    {
666
0
        EPROSIMA_LOG_ERROR(PARTICIPANT, "Number of expression parameters exceeds maximum protocol limit: "
667
0
                << expression_parameters.size() << " > 100");
668
0
        return nullptr;
669
0
    }
670
671
0
    TopicProxy* topic_impl = dynamic_cast<TopicProxy*>(related_topic->get_impl());
672
0
    assert(nullptr != topic_impl);
673
0
    const TypeSupport& type = topic_impl->get_type();
674
0
    LoanableSequence<const char*>::size_type n_params;
675
0
    n_params = static_cast<LoanableSequence<const char*>::size_type>(expression_parameters.size());
676
0
    LoanableSequence<const char*> filter_parameters(n_params);
677
0
    filter_parameters.length(n_params);
678
0
    while (n_params > 0)
679
0
    {
680
0
        n_params--;
681
0
        filter_parameters[n_params] = expression_parameters[n_params].c_str();
682
0
    }
683
684
    // Tell filter factory to compile the expression
685
0
    IContentFilter* filter_instance = nullptr;
686
0
    if (RETCODE_OK !=
687
0
            filter_factory->create_content_filter(filter_class_name, related_topic->get_type_name().c_str(),
688
0
            type.get(), filter_expression.c_str(), filter_parameters, filter_instance))
689
0
    {
690
0
        EPROSIMA_LOG_ERROR(PARTICIPANT, "Could not create filter of class " << filter_class_name << " for expression \""
691
0
                                                                            << filter_expression);
692
0
        return nullptr;
693
0
    }
694
695
0
    ContentFilteredTopic* topic;
696
0
    topic = new ContentFilteredTopic(name, related_topic, filter_expression, expression_parameters);
697
0
    ContentFilteredTopicImpl* content_topic_impl = static_cast<ContentFilteredTopicImpl*>(topic->get_impl());
698
0
    content_topic_impl->filter_property.filter_class_name = filter_class_name;
699
0
    content_topic_impl->filter_factory = filter_factory;
700
0
    content_topic_impl->filter_instance = filter_instance;
701
0
    content_topic_impl->update_signature();
702
703
    // Save the topic into the map
704
0
    filtered_topics_.emplace(std::make_pair(name, std::unique_ptr<ContentFilteredTopic>(topic)));
705
706
0
    return topic;
707
0
}
708
709
ReturnCode_t DomainParticipantImpl::delete_contentfilteredtopic(
710
        const ContentFilteredTopic* topic)
711
0
{
712
0
    if (topic == nullptr)
713
0
    {
714
0
        return RETCODE_BAD_PARAMETER;
715
0
    }
716
717
0
    std::lock_guard<std::mutex> lock(mtx_topics_);
718
0
    auto it = filtered_topics_.find(topic->get_name());
719
720
0
    if (it != filtered_topics_.end())
721
0
    {
722
0
        if (it->second->get_impl()->is_referenced())
723
0
        {
724
0
            return RETCODE_PRECONDITION_NOT_MET;
725
0
        }
726
0
        filtered_topics_.erase(it);
727
0
        return RETCODE_OK;
728
0
    }
729
730
0
    return RETCODE_PRECONDITION_NOT_MET;
731
0
}
732
733
ReturnCode_t DomainParticipantImpl::register_content_filter_factory(
734
        const char* filter_class_name,
735
        IContentFilterFactory* const filter_factory)
736
0
{
737
0
    if (nullptr == filter_factory || nullptr == filter_class_name || strlen(filter_class_name) > 255)
738
0
    {
739
0
        return RETCODE_BAD_PARAMETER;
740
0
    }
741
742
0
    std::lock_guard<std::mutex> lock(mtx_topics_);
743
0
    auto it = filter_factories_.find(filter_class_name);
744
0
    if ((it != filter_factories_.end()) || (0 == strcmp(filter_class_name, FASTDDS_SQLFILTER_NAME)))
745
0
    {
746
0
        return RETCODE_PRECONDITION_NOT_MET;
747
0
    }
748
749
0
    filter_factories_[filter_class_name] = filter_factory;
750
0
    return RETCODE_OK;
751
0
}
752
753
IContentFilterFactory* DomainParticipantImpl::lookup_content_filter_factory(
754
        const char* filter_class_name)
755
0
{
756
0
    if (nullptr == filter_class_name)
757
0
    {
758
0
        return nullptr;
759
0
    }
760
761
0
    std::lock_guard<std::mutex> lock(mtx_topics_);
762
0
    auto it = filter_factories_.find(filter_class_name);
763
0
    if ((it == filter_factories_.end()) || (it->first == FASTDDS_SQLFILTER_NAME))
764
0
    {
765
0
        return nullptr;
766
0
    }
767
0
    return it->second;
768
0
}
769
770
ReturnCode_t DomainParticipantImpl::unregister_content_filter_factory(
771
        const char* filter_class_name)
772
0
{
773
0
    if (nullptr == filter_class_name)
774
0
    {
775
0
        return RETCODE_BAD_PARAMETER;
776
0
    }
777
778
0
    std::lock_guard<std::mutex> lock(mtx_topics_);
779
0
    auto it = filter_factories_.find(filter_class_name);
780
0
    if ((it == filter_factories_.end()) || (it->first == FASTDDS_SQLFILTER_NAME))
781
0
    {
782
0
        return RETCODE_PRECONDITION_NOT_MET;
783
0
    }
784
785
0
    for (auto& topic : filtered_topics_)
786
0
    {
787
0
        if (topic.second->impl_->filter_property.filter_class_name == filter_class_name)
788
0
        {
789
0
            return RETCODE_PRECONDITION_NOT_MET;
790
0
        }
791
0
    }
792
793
0
    for (auto& pub : publishers_)
794
0
    {
795
0
        for (auto& topic : pub.second->writers_)
796
0
        {
797
0
            for (auto& wr : topic.second)
798
0
            {
799
0
                wr->filter_is_being_removed(filter_class_name);
800
0
            }
801
0
        }
802
0
    }
803
804
0
    filter_factories_.erase(it);
805
806
0
    return RETCODE_OK;
807
0
}
808
809
IContentFilterFactory* DomainParticipantImpl::find_content_filter_factory(
810
        const char* filter_class_name)
811
0
{
812
0
    auto it = filter_factories_.find(filter_class_name);
813
0
    if (it != filter_factories_.end())
814
0
    {
815
0
        return it->second;
816
0
    }
817
818
0
    if (0 != strcmp(filter_class_name, FASTDDS_SQLFILTER_NAME))
819
0
    {
820
0
        return nullptr;
821
0
    }
822
823
0
    return &dds_sql_filter_factory_;
824
0
}
825
826
InstanceHandle_t DomainParticipantImpl::get_instance_handle() const
827
0
{
828
0
    return handle_;
829
0
}
830
831
const fastdds::rtps::GUID_t& DomainParticipantImpl::guid() const
832
0
{
833
0
    return guid_;
834
0
}
835
836
Publisher* DomainParticipantImpl::create_publisher(
837
        const PublisherQos& qos,
838
        ReturnCode_t& ret_code,
839
        PublisherListener* listener,
840
        const StatusMask& mask)
841
0
{
842
0
    Publisher* pub = create_publisher(qos, listener, mask);
843
0
    ret_code = (pub != nullptr) ? RETCODE_OK : RETCODE_ERROR;
844
0
    return pub;
845
0
}
846
847
Publisher* DomainParticipantImpl::create_publisher(
848
        const PublisherQos& qos,
849
        PublisherListener* listener,
850
        const StatusMask& mask)
851
0
{
852
0
    return create_publisher(qos, nullptr, listener, mask);
853
0
}
854
855
Publisher* DomainParticipantImpl::create_publisher(
856
        const PublisherQos& qos,
857
        PublisherImpl** impl,
858
        PublisherListener* listener,
859
        const StatusMask& mask)
860
0
{
861
0
    if (RETCODE_OK != PublisherImpl::check_qos(qos))
862
0
    {
863
        // The PublisherImpl::check_qos() function is not yet implemented and always returns RETCODE_OK.
864
        // It will be implemented in future releases of Fast DDS.
865
        // EPROSIMA_LOG_ERROR(PARTICIPANT, "PublisherQos inconsistent or not supported");
866
        // return nullptr;
867
0
    }
868
869
    //TODO CONSTRUIR LA IMPLEMENTACION DENTRO DEL OBJETO DEL USUARIO.
870
0
    PublisherImpl* pubimpl = create_publisher_impl(qos, listener);
871
0
    Publisher* pub = new Publisher(pubimpl, mask);
872
0
    pubimpl->user_publisher_ = pub;
873
0
    pubimpl->rtps_participant_ = get_rtps_participant();
874
0
    bool enabled = get_rtps_participant() != nullptr;
875
876
    // Create InstanceHandle for the new publisher
877
0
    InstanceHandle_t pub_handle;
878
0
    create_instance_handle(pub_handle);
879
0
    pubimpl->handle_ = pub_handle;
880
881
    //SAVE THE PUBLISHER INTO MAPS
882
0
    std::lock_guard<std::mutex> lock(mtx_pubs_);
883
0
    publishers_by_handle_[pub_handle] = pub;
884
0
    publishers_[pub] = pubimpl;
885
886
    // Enable publisher if appropriate
887
0
    if (enabled && qos_.entity_factory().autoenable_created_entities)
888
0
    {
889
0
        ReturnCode_t ret_publisher_enable = pub->enable();
890
0
        assert(RETCODE_OK == ret_publisher_enable);
891
0
        (void)ret_publisher_enable;
892
0
    }
893
894
0
    if (impl)
895
0
    {
896
0
        *impl = pubimpl;
897
0
    }
898
899
0
    return pub;
900
0
}
901
902
Publisher* DomainParticipantImpl::create_publisher_with_profile(
903
        const std::string& profile_name,
904
        ReturnCode_t& ret_code,
905
        PublisherListener* listener,
906
        const StatusMask& mask)
907
0
{
908
0
    Publisher* pub = create_publisher_with_profile(profile_name, listener, mask);
909
0
    ret_code = (pub != nullptr) ? RETCODE_OK : RETCODE_ERROR;
910
0
    return pub;
911
0
}
912
913
Publisher* DomainParticipantImpl::create_publisher_with_profile(
914
        const std::string& profile_name,
915
        PublisherListener* listener,
916
        const StatusMask& mask)
917
0
{
918
    // TODO (ILG): Change when we have full XML support for DDS QoS profiles
919
0
    xmlparser::PublisherAttributes attr;
920
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fillPublisherAttributes(profile_name, attr))
921
0
    {
922
0
        PublisherQos qos = default_pub_qos_;
923
0
        utils::set_qos_from_attributes(qos, attr);
924
0
        return create_publisher(qos, listener, mask);
925
0
    }
926
927
0
    return nullptr;
928
0
}
929
930
PublisherImpl* DomainParticipantImpl::create_publisher_impl(
931
        const PublisherQos& qos,
932
        PublisherListener* listener)
933
0
{
934
0
    return new PublisherImpl(this, qos, listener);
935
0
}
936
937
/* TODO
938
   Subscriber* DomainParticipantImpl::get_builtin_subscriber()
939
   {
940
    EPROSIMA_LOG_ERROR(PARTICIPANT, "Not implemented.");
941
    return nullptr;
942
   }
943
 */
944
945
ReturnCode_t DomainParticipantImpl::ignore_participant(
946
        const InstanceHandle_t& handle)
947
0
{
948
0
    return (nullptr == rtps_participant_) ? RETCODE_NOT_ENABLED :
949
0
           rtps_participant_->ignore_participant(iHandle2GUID(handle).guidPrefix) ? RETCODE_OK :
950
0
           RETCODE_BAD_PARAMETER;
951
0
}
952
953
/* TODO
954
   bool DomainParticipantImpl::ignore_topic(
955
        const InstanceHandle_t& handle)
956
   {
957
    (void)handle;
958
    EPROSIMA_LOG_ERROR(PARTICIPANT, "Not implemented.");
959
    return false;
960
   }
961
 */
962
963
bool DomainParticipantImpl::ignore_publication(
964
        const InstanceHandle_t& handle)
965
0
{
966
0
    static_cast<void>(handle);
967
0
    EPROSIMA_LOG_ERROR(PARTICIPANT, "Not implemented.");
968
0
    return false;
969
0
}
970
971
bool DomainParticipantImpl::ignore_subscription(
972
        const InstanceHandle_t& handle)
973
0
{
974
0
    static_cast<void>(handle);
975
0
    EPROSIMA_LOG_ERROR(PARTICIPANT, "Not implemented.");
976
0
    return false;
977
0
}
978
979
DomainId_t DomainParticipantImpl::get_domain_id() const
980
0
{
981
0
    return domain_id_;
982
0
}
983
984
ReturnCode_t DomainParticipantImpl::delete_contained_entities()
985
0
{
986
0
    bool can_be_deleted = true;
987
988
0
    std::lock_guard<std::mutex> lock_subscribers(mtx_subs_);
989
990
0
    for (auto subscriber : subscribers_)
991
0
    {
992
0
        can_be_deleted = subscriber.second->can_be_deleted();
993
0
        if (!can_be_deleted)
994
0
        {
995
0
            return RETCODE_PRECONDITION_NOT_MET;
996
0
        }
997
0
    }
998
999
0
    std::lock_guard<std::mutex> lock_publishers(mtx_pubs_);
1000
1001
1002
1003
0
    for (auto publisher : publishers_)
1004
0
    {
1005
0
        can_be_deleted = publisher.second->can_be_deleted();
1006
0
        if (!can_be_deleted)
1007
0
        {
1008
0
            return RETCODE_PRECONDITION_NOT_MET;
1009
0
        }
1010
0
    }
1011
1012
0
    ReturnCode_t ret_code = RETCODE_OK;
1013
1014
0
    for (auto& subscriber : subscribers_)
1015
0
    {
1016
0
        ret_code = subscriber.first->delete_contained_entities();
1017
0
        if (RETCODE_OK != ret_code)
1018
0
        {
1019
0
            return RETCODE_ERROR;
1020
0
        }
1021
0
    }
1022
1023
0
    auto it_subs = subscribers_.begin();
1024
0
    while (it_subs != subscribers_.end())
1025
0
    {
1026
0
        it_subs->second->set_listener(nullptr);
1027
0
        subscribers_by_handle_.erase(it_subs->second->get_subscriber()->get_instance_handle());
1028
0
        delete it_subs->second;
1029
0
        it_subs = subscribers_.erase(it_subs);
1030
0
    }
1031
1032
0
    for (auto& publisher : publishers_)
1033
0
    {
1034
0
        ret_code = publisher.first->delete_contained_entities();
1035
0
        if (RETCODE_OK != ret_code)
1036
0
        {
1037
0
            return RETCODE_ERROR;
1038
0
        }
1039
0
    }
1040
1041
0
    auto it_pubs = publishers_.begin();
1042
0
    while (it_pubs != publishers_.end())
1043
0
    {
1044
0
        it_pubs->second->set_listener(nullptr);
1045
0
        publishers_by_handle_.erase(it_pubs->second->get_publisher()->get_instance_handle());
1046
0
        delete it_pubs->second;
1047
0
        it_pubs = publishers_.erase(it_pubs);
1048
0
    }
1049
1050
0
    std::lock_guard<std::mutex> lock_topics(mtx_topics_);
1051
1052
0
    filtered_topics_.clear();
1053
0
    topics_by_handle_.clear();
1054
1055
0
    auto it_topics = topics_.begin();
1056
0
    while (it_topics != topics_.end())
1057
0
    {
1058
0
        delete it_topics->second;
1059
0
        it_topics = topics_.erase(it_topics);
1060
0
    }
1061
1062
0
    return RETCODE_OK;
1063
0
}
1064
1065
ReturnCode_t DomainParticipantImpl::assert_liveliness()
1066
0
{
1067
0
    fastdds::rtps::RTPSParticipant* rtps_participant = get_rtps_participant();
1068
0
    if (rtps_participant == nullptr)
1069
0
    {
1070
0
        return RETCODE_NOT_ENABLED;
1071
0
    }
1072
1073
0
    if (rtps_participant->wlp() != nullptr)
1074
0
    {
1075
0
        if (rtps_participant->wlp()->assert_liveliness_manual_by_participant())
1076
0
        {
1077
0
            return RETCODE_OK;
1078
0
        }
1079
0
    }
1080
0
    else
1081
0
    {
1082
0
        EPROSIMA_LOG_ERROR(PARTICIPANT, "Invalid WLP, cannot assert liveliness of participant");
1083
0
    }
1084
0
    return RETCODE_ERROR;
1085
0
}
1086
1087
ReturnCode_t DomainParticipantImpl::set_default_publisher_qos(
1088
        const PublisherQos& qos)
1089
0
{
1090
0
    if (&qos == &PUBLISHER_QOS_DEFAULT)
1091
0
    {
1092
0
        reset_default_publisher_qos();
1093
0
        return RETCODE_OK;
1094
0
    }
1095
1096
0
    ReturnCode_t ret_val = PublisherImpl::check_qos(qos);
1097
0
    if (RETCODE_OK != ret_val)
1098
0
    {
1099
        // The PublisherImpl::check_qos() function is not yet implemented and always returns RETCODE_OK.
1100
        // It will be implemented in future releases of Fast DDS.
1101
        // return ret_val;
1102
0
    }
1103
0
    PublisherImpl::set_qos(default_pub_qos_, qos, true);
1104
0
    return RETCODE_OK;
1105
0
}
1106
1107
void DomainParticipantImpl::reset_default_publisher_qos()
1108
0
{
1109
    // TODO (ILG): Change when we have full XML support for DDS QoS profiles
1110
0
    PublisherImpl::set_qos(default_pub_qos_, PUBLISHER_QOS_DEFAULT, true);
1111
0
    xmlparser::PublisherAttributes attr;
1112
0
    XMLProfileManager::getDefaultPublisherAttributes(attr);
1113
0
    utils::set_qos_from_attributes(default_pub_qos_, attr);
1114
0
}
1115
1116
const PublisherQos& DomainParticipantImpl::get_default_publisher_qos() const
1117
0
{
1118
0
    return default_pub_qos_;
1119
0
}
1120
1121
ReturnCode_t DomainParticipantImpl::get_publisher_qos_from_profile(
1122
        const std::string& profile_name,
1123
        PublisherQos& qos) const
1124
0
{
1125
0
    xmlparser::PublisherAttributes attr;
1126
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fillPublisherAttributes(profile_name, attr))
1127
0
    {
1128
0
        qos = default_pub_qos_;
1129
0
        utils::set_qos_from_attributes(qos, attr);
1130
0
        return RETCODE_OK;
1131
0
    }
1132
1133
0
    return RETCODE_BAD_PARAMETER;
1134
0
}
1135
1136
ReturnCode_t DomainParticipantImpl::get_publisher_qos_from_xml(
1137
        const std::string& xml,
1138
        PublisherQos& qos) const
1139
0
{
1140
0
    xmlparser::PublisherAttributes attr;
1141
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_publisher_attributes_from_xml(xml, attr, false))
1142
0
    {
1143
0
        qos = default_pub_qos_;
1144
0
        utils::set_qos_from_attributes(qos, attr);
1145
0
        return RETCODE_OK;
1146
0
    }
1147
1148
0
    return RETCODE_BAD_PARAMETER;
1149
0
}
1150
1151
ReturnCode_t DomainParticipantImpl::get_publisher_qos_from_xml(
1152
        const std::string& xml,
1153
        PublisherQos& qos,
1154
        const std::string& profile_name) const
1155
0
{
1156
0
    if (profile_name.empty())
1157
0
    {
1158
0
        EPROSIMA_LOG_ERROR(DOMAIN_PARTICIPANT, "Provided profile name must be non-empty");
1159
0
        return RETCODE_BAD_PARAMETER;
1160
0
    }
1161
1162
0
    xmlparser::PublisherAttributes attr;
1163
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_publisher_attributes_from_xml(xml, attr, true, profile_name))
1164
0
    {
1165
0
        qos = default_pub_qos_;
1166
0
        utils::set_qos_from_attributes(qos, attr);
1167
0
        return RETCODE_OK;
1168
0
    }
1169
1170
0
    return RETCODE_BAD_PARAMETER;
1171
0
}
1172
1173
ReturnCode_t DomainParticipantImpl::get_default_publisher_qos_from_xml(
1174
        const std::string& xml,
1175
        PublisherQos& qos) const
1176
0
{
1177
0
    xmlparser::PublisherAttributes attr;
1178
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_default_publisher_attributes_from_xml(xml, attr, true))
1179
0
    {
1180
0
        qos = default_pub_qos_;
1181
0
        utils::set_qos_from_attributes(qos, attr);
1182
0
        return RETCODE_OK;
1183
0
    }
1184
1185
0
    return RETCODE_BAD_PARAMETER;
1186
0
}
1187
1188
ReturnCode_t DomainParticipantImpl::set_default_subscriber_qos(
1189
        const SubscriberQos& qos)
1190
0
{
1191
0
    if (&qos == &SUBSCRIBER_QOS_DEFAULT)
1192
0
    {
1193
0
        reset_default_subscriber_qos();
1194
0
        return RETCODE_OK;
1195
0
    }
1196
0
    ReturnCode_t check_result = SubscriberImpl::check_qos(qos);
1197
0
    if (RETCODE_OK != check_result)
1198
0
    {
1199
        // The SubscriberImpl::check_qos() function is not yet implemented and always returns RETCODE_OK.
1200
        // It will be implemented in future releases of Fast DDS.
1201
        // return check_result;
1202
0
    }
1203
0
    SubscriberImpl::set_qos(default_sub_qos_, qos, true);
1204
0
    return RETCODE_OK;
1205
0
}
1206
1207
void DomainParticipantImpl::reset_default_subscriber_qos()
1208
0
{
1209
    // TODO (ILG): Change when we have full XML support for DDS QoS profiles
1210
0
    SubscriberImpl::set_qos(default_sub_qos_, SUBSCRIBER_QOS_DEFAULT, true);
1211
0
    xmlparser::SubscriberAttributes attr;
1212
0
    XMLProfileManager::getDefaultSubscriberAttributes(attr);
1213
0
    utils::set_qos_from_attributes(default_sub_qos_, attr);
1214
0
}
1215
1216
const SubscriberQos& DomainParticipantImpl::get_default_subscriber_qos() const
1217
0
{
1218
0
    return default_sub_qos_;
1219
0
}
1220
1221
ReturnCode_t DomainParticipantImpl::get_subscriber_qos_from_profile(
1222
        const std::string& profile_name,
1223
        SubscriberQos& qos) const
1224
0
{
1225
0
    xmlparser::SubscriberAttributes attr;
1226
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fillSubscriberAttributes(profile_name, attr))
1227
0
    {
1228
0
        qos = default_sub_qos_;
1229
0
        utils::set_qos_from_attributes(qos, attr);
1230
0
        return RETCODE_OK;
1231
0
    }
1232
1233
0
    return RETCODE_BAD_PARAMETER;
1234
0
}
1235
1236
ReturnCode_t DomainParticipantImpl::get_subscriber_qos_from_xml(
1237
        const std::string& xml,
1238
        SubscriberQos& qos) const
1239
0
{
1240
0
    xmlparser::SubscriberAttributes attr;
1241
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_subscriber_attributes_from_xml(xml, attr, false))
1242
0
    {
1243
0
        qos = default_sub_qos_;
1244
0
        utils::set_qos_from_attributes(qos, attr);
1245
0
        return RETCODE_OK;
1246
0
    }
1247
1248
0
    return RETCODE_BAD_PARAMETER;
1249
0
}
1250
1251
ReturnCode_t DomainParticipantImpl::get_subscriber_qos_from_xml(
1252
        const std::string& xml,
1253
        SubscriberQos& qos,
1254
        const std::string& profile_name) const
1255
0
{
1256
0
    if (profile_name.empty())
1257
0
    {
1258
0
        EPROSIMA_LOG_ERROR(DOMAIN_PARTICIPANT, "Provided profile name must be non-empty");
1259
0
        return RETCODE_BAD_PARAMETER;
1260
0
    }
1261
1262
0
    xmlparser::SubscriberAttributes attr;
1263
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_subscriber_attributes_from_xml(xml, attr, true, profile_name))
1264
0
    {
1265
0
        qos = default_sub_qos_;
1266
0
        utils::set_qos_from_attributes(qos, attr);
1267
0
        return RETCODE_OK;
1268
0
    }
1269
1270
0
    return RETCODE_BAD_PARAMETER;
1271
0
}
1272
1273
ReturnCode_t DomainParticipantImpl::get_default_subscriber_qos_from_xml(
1274
        const std::string& xml,
1275
        SubscriberQos& qos) const
1276
0
{
1277
0
    xmlparser::SubscriberAttributes attr;
1278
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_default_subscriber_attributes_from_xml(xml, attr, true))
1279
0
    {
1280
0
        qos = default_sub_qos_;
1281
0
        utils::set_qos_from_attributes(qos, attr);
1282
0
        return RETCODE_OK;
1283
0
    }
1284
1285
0
    return RETCODE_BAD_PARAMETER;
1286
0
}
1287
1288
ReturnCode_t DomainParticipantImpl::set_default_topic_qos(
1289
        const TopicQos& qos)
1290
0
{
1291
0
    if (&qos == &TOPIC_QOS_DEFAULT)
1292
0
    {
1293
0
        reset_default_topic_qos();
1294
0
        return RETCODE_OK;
1295
0
    }
1296
1297
0
    ReturnCode_t ret_val = TopicImpl::check_qos(qos);
1298
0
    if (RETCODE_OK != ret_val)
1299
0
    {
1300
0
        return ret_val;
1301
0
    }
1302
1303
0
    TopicImpl::set_qos(default_topic_qos_, qos, true);
1304
0
    return RETCODE_OK;
1305
0
}
1306
1307
void DomainParticipantImpl::reset_default_topic_qos()
1308
0
{
1309
    // TODO (ILG): Change when we have full XML support for DDS QoS profiles
1310
0
    TopicImpl::set_qos(default_topic_qos_, TOPIC_QOS_DEFAULT, true);
1311
0
    xmlparser::TopicAttributes attr;
1312
0
    XMLProfileManager::getDefaultTopicAttributes(attr);
1313
0
    utils::set_qos_from_attributes(default_topic_qos_, attr);
1314
0
}
1315
1316
const TopicQos& DomainParticipantImpl::get_default_topic_qos() const
1317
0
{
1318
0
    return default_topic_qos_;
1319
0
}
1320
1321
ReturnCode_t DomainParticipantImpl::get_topic_qos_from_profile(
1322
        const std::string& profile_name,
1323
        TopicQos& qos) const
1324
0
{
1325
0
    std::string _topic_name, _topic_data_type;
1326
0
    return get_topic_qos_from_profile(profile_name, qos, _topic_name, _topic_data_type);
1327
0
}
1328
1329
ReturnCode_t DomainParticipantImpl::get_topic_qos_from_profile(
1330
        const std::string& profile_name,
1331
        TopicQos& qos,
1332
        std::string& topic_name,
1333
        std::string& topic_data_type) const
1334
0
{
1335
0
    xmlparser::TopicAttributes attr;
1336
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fillTopicAttributes(profile_name, attr))
1337
0
    {
1338
0
        qos = default_topic_qos_;
1339
0
        utils::set_qos_from_attributes(qos, attr);
1340
0
        topic_name = attr.getTopicName();
1341
0
        topic_data_type = attr.getTopicDataType();
1342
0
        return RETCODE_OK;
1343
0
    }
1344
1345
0
    return RETCODE_BAD_PARAMETER;
1346
0
}
1347
1348
ReturnCode_t DomainParticipantImpl::get_topic_qos_from_xml(
1349
        const std::string& xml,
1350
        TopicQos& qos) const
1351
0
{
1352
0
    std::string _topic_name, _topic_data_type;
1353
0
    return get_topic_qos_from_xml(xml, qos, _topic_name, _topic_data_type);
1354
0
}
1355
1356
ReturnCode_t DomainParticipantImpl::get_topic_qos_from_xml(
1357
        const std::string& xml,
1358
        TopicQos& qos,
1359
        std::string& topic_name,
1360
        std::string& topic_data_type) const
1361
0
{
1362
0
    xmlparser::TopicAttributes attr;
1363
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_topic_attributes_from_xml(xml, attr, false))
1364
0
    {
1365
0
        qos = default_topic_qos_;
1366
0
        utils::set_qos_from_attributes(qos, attr);
1367
0
        topic_name = attr.getTopicName();
1368
0
        topic_data_type = attr.getTopicDataType();
1369
0
        return RETCODE_OK;
1370
0
    }
1371
1372
0
    return RETCODE_BAD_PARAMETER;
1373
0
}
1374
1375
ReturnCode_t DomainParticipantImpl::get_topic_qos_from_xml(
1376
        const std::string& xml,
1377
        TopicQos& qos,
1378
        const std::string& profile_name) const
1379
0
{
1380
0
    std::string _topic_name, _topic_data_type;
1381
0
    return get_topic_qos_from_xml(xml, qos, _topic_name, _topic_data_type, profile_name);
1382
0
}
1383
1384
ReturnCode_t DomainParticipantImpl::get_topic_qos_from_xml(
1385
        const std::string& xml,
1386
        TopicQos& qos,
1387
        std::string& topic_name,
1388
        std::string& topic_data_type,
1389
        const std::string& profile_name) const
1390
0
{
1391
0
    if (profile_name.empty())
1392
0
    {
1393
0
        EPROSIMA_LOG_ERROR(DOMAIN_PARTICIPANT, "Provided profile name must be non-empty");
1394
0
        return RETCODE_BAD_PARAMETER;
1395
0
    }
1396
1397
0
    xmlparser::TopicAttributes attr;
1398
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_topic_attributes_from_xml(xml, attr, true, profile_name))
1399
0
    {
1400
0
        qos = default_topic_qos_;
1401
0
        utils::set_qos_from_attributes(qos, attr);
1402
0
        topic_name = attr.getTopicName();
1403
0
        topic_data_type = attr.getTopicDataType();
1404
0
        return RETCODE_OK;
1405
0
    }
1406
1407
0
    return RETCODE_BAD_PARAMETER;
1408
0
}
1409
1410
ReturnCode_t DomainParticipantImpl::get_default_topic_qos_from_xml(
1411
        const std::string& xml,
1412
        TopicQos& qos) const
1413
0
{
1414
0
    std::string _topic_name, _topic_data_type;
1415
0
    return get_default_topic_qos_from_xml(xml, qos, _topic_name, _topic_data_type);
1416
0
}
1417
1418
ReturnCode_t DomainParticipantImpl::get_default_topic_qos_from_xml(
1419
        const std::string& xml,
1420
        TopicQos& qos,
1421
        std::string& topic_name,
1422
        std::string& topic_data_type) const
1423
0
{
1424
0
    xmlparser::TopicAttributes attr;
1425
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_default_topic_attributes_from_xml(xml, attr, true))
1426
0
    {
1427
0
        qos = default_topic_qos_;
1428
0
        utils::set_qos_from_attributes(qos, attr);
1429
0
        topic_name = attr.getTopicName();
1430
0
        topic_data_type = attr.getTopicDataType();
1431
0
        return RETCODE_OK;
1432
0
    }
1433
1434
0
    return RETCODE_BAD_PARAMETER;
1435
0
}
1436
1437
ReturnCode_t DomainParticipantImpl::get_replier_qos_from_profile(
1438
        const std::string& profile_name,
1439
        ReplierQos& qos) const
1440
0
{
1441
0
    xmlparser::ReplierAttributes attr;
1442
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fillReplierAttributes(profile_name, attr))
1443
0
    {
1444
0
        utils::set_qos_from_attributes(qos, attr);
1445
0
        return RETCODE_OK;
1446
0
    }
1447
1448
0
    return RETCODE_BAD_PARAMETER;
1449
0
}
1450
1451
ReturnCode_t DomainParticipantImpl::get_replier_qos_from_xml(
1452
        const std::string& xml,
1453
        ReplierQos& qos) const
1454
0
{
1455
0
    xmlparser::ReplierAttributes attr;
1456
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_replier_attributes_from_xml(xml, attr, false))
1457
0
    {
1458
0
        utils::set_qos_from_attributes(qos, attr);
1459
0
        return RETCODE_OK;
1460
0
    }
1461
1462
0
    return RETCODE_BAD_PARAMETER;
1463
0
}
1464
1465
ReturnCode_t DomainParticipantImpl::get_replier_qos_from_xml(
1466
        const std::string& xml,
1467
        ReplierQos& qos,
1468
        const std::string& profile_name) const
1469
0
{
1470
0
    if (profile_name.empty())
1471
0
    {
1472
0
        EPROSIMA_LOG_ERROR(DOMAIN_PARTICIPANT, "Provided profile name must be non-empty");
1473
0
        return RETCODE_BAD_PARAMETER;
1474
0
    }
1475
1476
0
    xmlparser::ReplierAttributes attr;
1477
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_replier_attributes_from_xml(xml, attr, true, profile_name))
1478
0
    {
1479
0
        utils::set_qos_from_attributes(qos, attr);
1480
0
        return RETCODE_OK;
1481
0
    }
1482
1483
0
    return RETCODE_BAD_PARAMETER;
1484
0
}
1485
1486
ReturnCode_t DomainParticipantImpl::get_default_replier_qos_from_xml(
1487
        const std::string& xml,
1488
        ReplierQos& qos) const
1489
0
{
1490
0
    xmlparser::ReplierAttributes attr;
1491
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_default_replier_attributes_from_xml(xml, attr, true))
1492
0
    {
1493
0
        utils::set_qos_from_attributes(qos, attr);
1494
0
        return RETCODE_OK;
1495
0
    }
1496
1497
0
    return RETCODE_BAD_PARAMETER;
1498
0
}
1499
1500
ReturnCode_t DomainParticipantImpl::get_requester_qos_from_profile(
1501
        const std::string& profile_name,
1502
        RequesterQos& qos) const
1503
0
{
1504
0
    xmlparser::RequesterAttributes attr;
1505
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fillRequesterAttributes(profile_name, attr))
1506
0
    {
1507
0
        utils::set_qos_from_attributes(qos, attr);
1508
0
        return RETCODE_OK;
1509
0
    }
1510
1511
0
    return RETCODE_BAD_PARAMETER;
1512
0
}
1513
1514
ReturnCode_t DomainParticipantImpl::get_requester_qos_from_xml(
1515
        const std::string& xml,
1516
        RequesterQos& qos) const
1517
0
{
1518
0
    xmlparser::RequesterAttributes attr;
1519
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_requester_attributes_from_xml(xml, attr, false))
1520
0
    {
1521
0
        utils::set_qos_from_attributes(qos, attr);
1522
0
        return RETCODE_OK;
1523
0
    }
1524
1525
0
    return RETCODE_BAD_PARAMETER;
1526
0
}
1527
1528
ReturnCode_t DomainParticipantImpl::get_requester_qos_from_xml(
1529
        const std::string& xml,
1530
        RequesterQos& qos,
1531
        const std::string& profile_name) const
1532
0
{
1533
0
    if (profile_name.empty())
1534
0
    {
1535
0
        EPROSIMA_LOG_ERROR(DOMAIN_PARTICIPANT, "Provided profile name must be non-empty");
1536
0
        return RETCODE_BAD_PARAMETER;
1537
0
    }
1538
1539
0
    xmlparser::RequesterAttributes attr;
1540
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_requester_attributes_from_xml(xml, attr, true, profile_name))
1541
0
    {
1542
0
        utils::set_qos_from_attributes(qos, attr);
1543
0
        return RETCODE_OK;
1544
0
    }
1545
1546
0
    return RETCODE_BAD_PARAMETER;
1547
0
}
1548
1549
ReturnCode_t DomainParticipantImpl::get_default_requester_qos_from_xml(
1550
        const std::string& xml,
1551
        RequesterQos& qos) const
1552
0
{
1553
0
    xmlparser::RequesterAttributes attr;
1554
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_default_requester_attributes_from_xml(xml, attr, true))
1555
0
    {
1556
0
        utils::set_qos_from_attributes(qos, attr);
1557
0
        return RETCODE_OK;
1558
0
    }
1559
1560
0
    return RETCODE_BAD_PARAMETER;
1561
0
}
1562
1563
/* TODO
1564
   bool DomainParticipantImpl::get_discovered_participants(
1565
        std::vector<InstanceHandle_t>& participant_handles) const
1566
   {
1567
    (void)participant_handles;
1568
    EPROSIMA_LOG_ERROR(PARTICIPANT, "Not implemented.");
1569
    return false;
1570
   }
1571
 */
1572
1573
/* TODO
1574
   bool DomainParticipantImpl::get_discovered_topics(
1575
        std::vector<InstanceHandle_t>& topic_handles) const
1576
   {
1577
    (void)topic_handles;
1578
    EPROSIMA_LOG_ERROR(PARTICIPANT, "Not implemented.");
1579
    return false;
1580
   }
1581
 */
1582
1583
bool DomainParticipantImpl::contains_entity(
1584
        const InstanceHandle_t& handle,
1585
        bool recursive) const
1586
0
{
1587
    // Look for publishers
1588
0
    {
1589
0
        std::lock_guard<std::mutex> lock(mtx_pubs_);
1590
0
        if (publishers_by_handle_.find(handle) != publishers_by_handle_.end())
1591
0
        {
1592
0
            return true;
1593
0
        }
1594
0
    }
1595
1596
    // Look for subscribers
1597
0
    {
1598
0
        std::lock_guard<std::mutex> lock(mtx_subs_);
1599
0
        if (subscribers_by_handle_.find(handle) != subscribers_by_handle_.end())
1600
0
        {
1601
0
            return true;
1602
0
        }
1603
0
    }
1604
1605
    // Look for topics
1606
0
    {
1607
0
        std::lock_guard<std::mutex> lock(mtx_topics_);
1608
0
        if (topics_by_handle_.find(handle) != topics_by_handle_.end())
1609
0
        {
1610
0
            return true;
1611
0
        }
1612
0
    }
1613
1614
0
    if (recursive)
1615
0
    {
1616
        // Look into publishers
1617
0
        {
1618
0
            std::lock_guard<std::mutex> lock(mtx_pubs_);
1619
0
            for (auto pit : publishers_)
1620
0
            {
1621
0
                if (pit.second->contains_entity(handle))
1622
0
                {
1623
0
                    return true;
1624
0
                }
1625
0
            }
1626
0
        }
1627
1628
        // Look into subscribers
1629
0
        {
1630
0
            std::lock_guard<std::mutex> lock(mtx_subs_);
1631
0
            for (auto sit : subscribers_)
1632
0
            {
1633
0
                if (sit.second->contains_entity(handle))
1634
0
                {
1635
0
                    return true;
1636
0
                }
1637
0
            }
1638
0
        }
1639
0
    }
1640
1641
0
    return false;
1642
0
}
1643
1644
ReturnCode_t DomainParticipantImpl::get_current_time(
1645
        fastdds::dds::Time_t& current_time) const
1646
0
{
1647
0
    fastdds::dds::Time_t::now(current_time);
1648
1649
0
    return RETCODE_OK;
1650
0
}
1651
1652
std::vector<std::string> DomainParticipantImpl::get_participant_names() const
1653
0
{
1654
0
    std::lock_guard<std::mutex> _(mtx_gs_);
1655
0
    return rtps_participant_ == nullptr ?
1656
0
           std::vector<std::string> {}
1657
0
           :
1658
0
           rtps_participant_->getParticipantNames();
1659
0
}
1660
1661
Subscriber* DomainParticipantImpl::create_subscriber(
1662
        const SubscriberQos& qos,
1663
        ReturnCode_t& ret_code,
1664
        SubscriberListener* listener,
1665
        const StatusMask& mask)
1666
0
{
1667
0
    Subscriber* subscriber = create_subscriber(qos, listener, mask);
1668
0
    ret_code = (subscriber != nullptr) ? RETCODE_OK : RETCODE_ERROR;
1669
0
    return subscriber;
1670
0
}
1671
1672
Subscriber* DomainParticipantImpl::create_subscriber(
1673
        const SubscriberQos& qos,
1674
        SubscriberListener* listener,
1675
        const StatusMask& mask)
1676
0
{
1677
0
    if (RETCODE_OK != SubscriberImpl::check_qos(qos))
1678
0
    {
1679
        // The SubscriberImpl::check_qos() function is not yet implemented and always returns RETCODE_OK.
1680
        // It will be implemented in future releases of Fast DDS.
1681
        // EPROSIMA_LOG_ERROR(PARTICIPANT, "SubscriberQos inconsistent or not supported");
1682
        // return nullptr;
1683
0
    }
1684
1685
    //TODO CONSTRUIR LA IMPLEMENTACION DENTRO DEL OBJETO DEL USUARIO.
1686
0
    SubscriberImpl* subimpl = create_subscriber_impl(qos, listener);
1687
0
    Subscriber* sub = new Subscriber(subimpl, mask);
1688
0
    subimpl->user_subscriber_ = sub;
1689
0
    subimpl->rtps_participant_ = get_rtps_participant();
1690
1691
    // Create InstanceHandle for the new subscriber
1692
0
    InstanceHandle_t sub_handle;
1693
0
    bool enabled = get_rtps_participant() != nullptr;
1694
1695
    // Create InstanceHandle for the new subscriber
1696
0
    create_instance_handle(sub_handle);
1697
0
    subimpl->handle_ = sub_handle;
1698
1699
    //SAVE THE PUBLISHER INTO MAPS
1700
0
    std::lock_guard<std::mutex> lock(mtx_subs_);
1701
0
    subscribers_by_handle_[sub_handle] = sub;
1702
0
    subscribers_[sub] = subimpl;
1703
1704
    // Enable subscriber if appropriate
1705
0
    if (enabled && qos_.entity_factory().autoenable_created_entities)
1706
0
    {
1707
0
        ReturnCode_t ret_subscriber_enable = sub->enable();
1708
0
        assert(RETCODE_OK == ret_subscriber_enable);
1709
0
        (void)ret_subscriber_enable;
1710
0
    }
1711
1712
0
    return sub;
1713
0
}
1714
1715
Subscriber* DomainParticipantImpl::create_subscriber_with_profile(
1716
        const std::string& profile_name,
1717
        ReturnCode_t& ret_code,
1718
        SubscriberListener* listener,
1719
        const StatusMask& mask)
1720
0
{
1721
0
    Subscriber* subscriber = create_subscriber_with_profile(profile_name, listener, mask);
1722
0
    ret_code = (subscriber != nullptr) ? RETCODE_OK : RETCODE_ERROR;
1723
0
    return subscriber;
1724
0
}
1725
1726
Subscriber* DomainParticipantImpl::create_subscriber_with_profile(
1727
        const std::string& profile_name,
1728
        SubscriberListener* listener,
1729
        const StatusMask& mask)
1730
0
{
1731
    // TODO (ILG): Change when we have full XML support for DDS QoS profiles
1732
0
    xmlparser::SubscriberAttributes attr;
1733
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fillSubscriberAttributes(profile_name, attr))
1734
0
    {
1735
0
        SubscriberQos qos = default_sub_qos_;
1736
0
        utils::set_qos_from_attributes(qos, attr);
1737
0
        return create_subscriber(qos, listener, mask);
1738
0
    }
1739
1740
0
    return nullptr;
1741
0
}
1742
1743
SubscriberImpl* DomainParticipantImpl::create_subscriber_impl(
1744
        const SubscriberQos& qos,
1745
        SubscriberListener* listener)
1746
0
{
1747
0
    return new SubscriberImpl(this, qos, listener);
1748
0
}
1749
1750
Topic* DomainParticipantImpl::create_topic(
1751
        const std::string& topic_name,
1752
        const std::string& type_name,
1753
        const TopicQos& qos,
1754
        ReturnCode_t& ret_code,
1755
        TopicListener* listener,
1756
        const StatusMask& mask)
1757
0
{
1758
0
    Topic * topic = create_topic(topic_name, type_name, qos, listener, mask);
1759
0
    ret_code = (topic != nullptr) ? RETCODE_OK : RETCODE_ERROR;
1760
0
    return topic;
1761
0
}
1762
1763
Topic* DomainParticipantImpl::create_topic(
1764
        const std::string& topic_name,
1765
        const std::string& type_name,
1766
        const TopicQos& qos,
1767
        TopicListener* listener,
1768
        const StatusMask& mask)
1769
0
{
1770
    //Look for the correct type registration
1771
0
    TypeSupport type_support = find_type(type_name);
1772
0
    if (type_support.empty())
1773
0
    {
1774
0
        EPROSIMA_LOG_ERROR(PARTICIPANT, "Type : " << type_name << " Not Registered");
1775
0
        return nullptr;
1776
0
    }
1777
1778
0
    if (RETCODE_OK != TopicImpl::check_qos_including_resource_limits(qos, type_support))
1779
0
    {
1780
0
        EPROSIMA_LOG_ERROR(PARTICIPANT, "TopicQos inconsistent or not supported");
1781
0
        return nullptr;
1782
0
    }
1783
1784
0
    bool enabled = get_rtps_participant() != nullptr;
1785
1786
0
    std::lock_guard<std::mutex> lock(mtx_topics_);
1787
1788
    // Check there is no Topic with the same name
1789
0
    if ((topics_.find(topic_name) != topics_.end()) ||
1790
0
            (filtered_topics_.find(topic_name) != filtered_topics_.end()))
1791
0
    {
1792
0
        EPROSIMA_LOG_ERROR(PARTICIPANT, "Topic with name : " << topic_name << " already exists");
1793
0
        return nullptr;
1794
0
    }
1795
1796
0
    InstanceHandle_t topic_handle;
1797
0
    create_instance_handle(topic_handle);
1798
1799
0
    TopicProxyFactory* factory = new TopicProxyFactory(this, topic_name, type_name, mask, type_support, qos, listener);
1800
0
    TopicProxy* proxy = factory->create_topic();
1801
0
    Topic* topic = proxy->get_topic();
1802
0
    topic->set_instance_handle(topic_handle);
1803
1804
    //SAVE THE TOPIC INTO MAPS
1805
0
    topics_by_handle_[topic_handle] = topic;
1806
0
    topics_[topic_name] = factory;
1807
1808
    // Enable topic if appropriate
1809
0
    if (enabled && qos_.entity_factory().autoenable_created_entities)
1810
0
    {
1811
0
        ReturnCode_t ret_topic_enable = topic->enable();
1812
0
        assert(RETCODE_OK == ret_topic_enable);
1813
0
        (void)ret_topic_enable;
1814
0
    }
1815
1816
0
    cond_topics_.notify_all();
1817
1818
0
    return topic;
1819
0
}
1820
1821
Topic* DomainParticipantImpl::create_topic_with_profile(
1822
        const std::string& topic_name,
1823
        const std::string& type_name,
1824
        const std::string& profile_name,
1825
        ReturnCode_t& ret_code,
1826
        TopicListener* listener,
1827
        const StatusMask& mask)
1828
0
{
1829
0
    Topic* topic = create_topic_with_profile(topic_name, type_name, profile_name, listener, mask);
1830
0
    ret_code = (topic != nullptr) ? RETCODE_OK : RETCODE_ERROR;
1831
0
    return topic;
1832
0
}
1833
1834
Topic* DomainParticipantImpl::create_topic_with_profile(
1835
        const std::string& topic_name,
1836
        const std::string& type_name,
1837
        const std::string& profile_name,
1838
        TopicListener* listener,
1839
        const StatusMask& mask)
1840
0
{
1841
    // TODO (ILG): Change when we have full XML support for DDS QoS profiles
1842
0
    xmlparser::TopicAttributes attr;
1843
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fillTopicAttributes(profile_name, attr))
1844
0
    {
1845
0
        TopicQos qos = default_topic_qos_;
1846
0
        utils::set_qos_from_attributes(qos, attr);
1847
0
        return create_topic(topic_name, type_name, qos, listener, mask);
1848
0
    }
1849
1850
0
    return nullptr;
1851
0
}
1852
1853
TopicDescription* DomainParticipantImpl::lookup_topicdescription(
1854
        const std::string& topic_name) const
1855
0
{
1856
0
    std::lock_guard<std::mutex> lock(mtx_topics_);
1857
1858
0
    auto it = topics_.find(topic_name);
1859
0
    if (it != topics_.end())
1860
0
    {
1861
0
        return it->second->get_topic()->get_topic();
1862
0
    }
1863
1864
0
    auto filtered_it = filtered_topics_.find(topic_name);
1865
0
    if (filtered_it != filtered_topics_.end())
1866
0
    {
1867
0
        return filtered_it->second.get();
1868
0
    }
1869
1870
0
    return nullptr;
1871
0
}
1872
1873
const TypeSupport DomainParticipantImpl::find_type(
1874
        const std::string& type_name) const
1875
0
{
1876
0
    std::lock_guard<std::mutex> lock(mtx_types_);
1877
1878
0
    auto type_it = types_.find(type_name);
1879
1880
0
    if (type_it != types_.end())
1881
0
    {
1882
0
        return type_it->second;
1883
0
    }
1884
1885
0
    return TypeSupport(nullptr);
1886
0
}
1887
1888
ReturnCode_t DomainParticipantImpl::register_type(
1889
        const TypeSupport type,
1890
        const std::string& type_name)
1891
0
{
1892
0
    if (type_name.size() <= 0)
1893
0
    {
1894
0
        EPROSIMA_LOG_ERROR(PARTICIPANT, "Registered Type must have a name");
1895
0
        return RETCODE_BAD_PARAMETER;
1896
0
    }
1897
1898
    /*
1899
     * The type object registration sets the TypeIdentifiers in the type support's underlying TopicDataType.
1900
     * This means that we need need to trigger the registration of the type object representation
1901
     * (idempotent operation) before finding the type in the registry.
1902
     * Otherwise, registering two TypeSupport instances with the same underlying TopicDataType will fail upon
1903
     * the second registration, as the TypeIdentifiers of the retrieved type from the registry would not be equal
1904
     * to those of the incoming type support.
1905
     */
1906
0
    type.get()->register_type_object_representation();
1907
1908
0
    TypeSupport t = find_type(type_name);
1909
1910
0
    if (!t.empty())
1911
0
    {
1912
0
        if (t == type)
1913
0
        {
1914
0
            return RETCODE_OK;
1915
0
        }
1916
1917
0
        EPROSIMA_LOG_ERROR(PARTICIPANT, "Another type with the same name '" << type_name << "' is already registered.");
1918
0
        return RETCODE_PRECONDITION_NOT_MET;
1919
0
    }
1920
1921
0
    EPROSIMA_LOG_INFO(PARTICIPANT, "Type " << type_name << " registered.");
1922
0
    std::lock_guard<std::mutex> lock(mtx_types_);
1923
0
    types_.insert(std::make_pair(type_name, type));
1924
1925
0
    return RETCODE_OK;
1926
0
}
1927
1928
ReturnCode_t DomainParticipantImpl::unregister_type(
1929
        const std::string& type_name)
1930
0
{
1931
0
    if (type_name.size() <= 0)
1932
0
    {
1933
0
        EPROSIMA_LOG_ERROR(PARTICIPANT, "Registered Type must have a name");
1934
0
        return RETCODE_BAD_PARAMETER;
1935
0
    }
1936
1937
0
    TypeSupport t = find_type(type_name);
1938
1939
0
    if (t.empty())
1940
0
    {
1941
0
        return RETCODE_OK; // Not registered, so unregistering complete.
1942
0
    }
1943
1944
0
    {
1945
        // Check is any subscriber is using the type
1946
0
        std::lock_guard<std::mutex> lock(mtx_subs_);
1947
1948
0
        for (auto sit : subscribers_)
1949
0
        {
1950
0
            if (sit.second->type_in_use(type_name))
1951
0
            {
1952
0
                EPROSIMA_LOG_WARNING(PARTICIPANT, "Type '" << type_name << "' is in use");
1953
0
                return RETCODE_PRECONDITION_NOT_MET;
1954
0
            }
1955
0
        }
1956
0
    }
1957
1958
0
    {
1959
        // Check is any publisher is using the type
1960
0
        std::lock_guard<std::mutex> lock(mtx_pubs_);
1961
1962
0
        for (auto pit : publishers_)
1963
0
        {
1964
0
            if (pit.second->type_in_use(type_name))
1965
0
            {
1966
0
                EPROSIMA_LOG_WARNING(PARTICIPANT, "Type '" << type_name << "' is in use");
1967
0
                return RETCODE_PRECONDITION_NOT_MET;
1968
0
            }
1969
0
        }
1970
0
    }
1971
1972
0
    std::lock_guard<std::mutex> lock(mtx_types_);
1973
0
    types_.erase(type_name);
1974
1975
0
    return RETCODE_OK;
1976
0
}
1977
1978
const rpc::ServiceTypeSupport DomainParticipantImpl::find_service_type(
1979
        const std::string& /*service_type_name*/) const
1980
0
{
1981
0
    EPROSIMA_LOG_ERROR(PARTICIPANT, "Services are not supported in this Fast DDS version");
1982
0
    return rpc::ServiceTypeSupport();
1983
0
}
1984
1985
ReturnCode_t DomainParticipantImpl::register_service_type(
1986
        rpc::ServiceTypeSupport /*service_type*/,
1987
        const std::string& /*service_type_name*/)
1988
0
{
1989
0
    EPROSIMA_LOG_ERROR(PARTICIPANT, "Services are not supported in this Fast DDS version");
1990
0
    return RETCODE_UNSUPPORTED;
1991
0
}
1992
1993
ReturnCode_t DomainParticipantImpl::unregister_service_type(
1994
        const std::string& /*service_type_name*/)
1995
0
{
1996
0
    EPROSIMA_LOG_ERROR(PARTICIPANT, "Services are not supported in this Fast DDS version");
1997
0
    return RETCODE_UNSUPPORTED;
1998
0
}
1999
2000
rpc::Service* DomainParticipantImpl::create_service(
2001
        const std::string& /*service_name*/,
2002
        const std::string& /*service_type_name*/,
2003
        ReturnCode_t& ret_code)
2004
0
{
2005
0
    ret_code = RETCODE_UNSUPPORTED;
2006
0
    return nullptr;
2007
0
}
2008
2009
rpc::Service* DomainParticipantImpl::create_service(
2010
        const std::string& service_name,
2011
        const std::string& service_type_name)
2012
0
{
2013
0
    ReturnCode_t ret_code;
2014
0
    rpc::Service* service = create_service(service_name, service_type_name, ret_code);
2015
0
    if (RETCODE_UNSUPPORTED == ret_code)
2016
0
    {
2017
0
        EPROSIMA_LOG_ERROR(PARTICIPANT, "Services are not supported in this Fast DDS version");
2018
0
    }
2019
0
    return service;
2020
0
}
2021
2022
rpc::Service* DomainParticipantImpl::find_service(
2023
        const std::string& /*service_name*/) const
2024
0
{
2025
0
    EPROSIMA_LOG_ERROR(PARTICIPANT, "Services are not supported in this Fast DDS version");
2026
0
    return nullptr;
2027
0
}
2028
2029
ReturnCode_t DomainParticipantImpl::delete_service(
2030
        const rpc::Service* /*service*/)
2031
0
{
2032
0
    EPROSIMA_LOG_ERROR(PARTICIPANT, "Services are not supported in this Fast DDS version");
2033
0
    return RETCODE_UNSUPPORTED;
2034
0
}
2035
2036
rpc::Requester* DomainParticipantImpl::create_service_requester(
2037
        rpc::Service* /*service*/,
2038
        const RequesterQos& /*requester_qos*/,
2039
        ReturnCode_t& ret_code)
2040
0
{
2041
0
    ret_code = RETCODE_UNSUPPORTED;
2042
0
    return nullptr;
2043
0
}
2044
2045
rpc::Requester* DomainParticipantImpl::create_service_requester(
2046
        rpc::Service* service,
2047
        const RequesterQos& qos)
2048
0
{
2049
0
    ReturnCode_t ret_code;
2050
0
    rpc::Requester* requester = create_service_requester(service, qos, ret_code);
2051
0
    if (RETCODE_UNSUPPORTED == ret_code)
2052
0
    {
2053
0
        EPROSIMA_LOG_ERROR(PARTICIPANT, "Services are not supported in this Fast DDS version");
2054
0
    }
2055
0
    return requester;
2056
0
}
2057
2058
ReturnCode_t DomainParticipantImpl::delete_service_requester(
2059
        const std::string& /*service_name*/,
2060
        rpc::Requester* /*requester*/)
2061
0
{
2062
0
    EPROSIMA_LOG_ERROR(PARTICIPANT, "Services are not supported in this Fast DDS version");
2063
0
    return RETCODE_UNSUPPORTED;
2064
0
}
2065
2066
rpc::Replier* DomainParticipantImpl::create_service_replier(
2067
        rpc::Service* /*service*/,
2068
        const ReplierQos& /*replier_qos*/,
2069
        ReturnCode_t& ret_code)
2070
0
{
2071
0
    ret_code = RETCODE_UNSUPPORTED;
2072
0
    return nullptr;
2073
0
}
2074
2075
rpc::Replier* DomainParticipantImpl::create_service_replier(
2076
        rpc::Service* service,
2077
        const ReplierQos& qos)
2078
0
{
2079
0
    ReturnCode_t ret_code;
2080
0
    rpc::Replier* replier = create_service_replier(service, qos, ret_code);
2081
0
    if (RETCODE_UNSUPPORTED == ret_code)
2082
0
    {
2083
0
        EPROSIMA_LOG_ERROR(PARTICIPANT, "Services are not supported in this Fast DDS version");
2084
0
    }
2085
0
    return replier;
2086
0
}
2087
2088
ReturnCode_t DomainParticipantImpl::delete_service_replier(
2089
        const std::string& /*service_name*/,
2090
        rpc::Replier* /*replier*/)
2091
0
{
2092
0
    EPROSIMA_LOG_ERROR(PARTICIPANT, "Services are not supported in this Fast DDS version");
2093
0
    return RETCODE_UNSUPPORTED;
2094
0
}
2095
2096
void DomainParticipantImpl::MyRTPSParticipantListener::on_participant_discovery(
2097
        RTPSParticipant*,
2098
        eprosima::fastdds::rtps::ParticipantDiscoveryStatus reason,
2099
        const ParticipantBuiltinTopicData& info,
2100
        bool& should_be_ignored)
2101
0
{
2102
0
    should_be_ignored = false;
2103
0
    Sentry sentinel(this);
2104
0
    if (sentinel)
2105
0
    {
2106
0
        participant_->listener_->on_participant_discovery(participant_->participant_, reason, std::move(info),
2107
0
                should_be_ignored);
2108
0
    }
2109
0
}
2110
2111
#if HAVE_SECURITY
2112
void DomainParticipantImpl::MyRTPSParticipantListener::onParticipantAuthentication(
2113
        RTPSParticipant*,
2114
        ParticipantAuthenticationInfo&& info)
2115
{
2116
    Sentry sentinel(this);
2117
    if (sentinel)
2118
    {
2119
        participant_->listener_->onParticipantAuthentication(participant_->participant_, std::move(info));
2120
    }
2121
}
2122
2123
#endif // if HAVE_SECURITY
2124
2125
void DomainParticipantImpl::MyRTPSParticipantListener::on_reader_discovery(
2126
        RTPSParticipant*,
2127
        ReaderDiscoveryStatus reason,
2128
        const SubscriptionBuiltinTopicData& info,
2129
        bool& should_be_ignored)
2130
0
{
2131
0
    should_be_ignored = false;
2132
2133
0
    Sentry sentinel(this);
2134
0
    if (sentinel)
2135
0
    {
2136
0
        DomainParticipantListener* listener = participant_->listener_;
2137
0
        if (nullptr != listener)
2138
0
        {
2139
0
            listener->on_data_reader_discovery(participant_->participant_, reason, info, should_be_ignored);
2140
0
        }
2141
0
    }
2142
0
}
2143
2144
void DomainParticipantImpl::MyRTPSParticipantListener::on_writer_discovery(
2145
        RTPSParticipant*,
2146
        WriterDiscoveryStatus reason,
2147
        const PublicationBuiltinTopicData& info,
2148
        bool& should_be_ignored)
2149
0
{
2150
0
    should_be_ignored = false;
2151
2152
0
    Sentry sentinel(this);
2153
0
    if (sentinel)
2154
0
    {
2155
0
        DomainParticipantListener* listener = participant_->listener_;
2156
0
        if (nullptr != listener)
2157
0
        {
2158
0
            listener->on_data_writer_discovery(participant_->participant_, reason, info, should_be_ignored);
2159
0
        }
2160
0
    }
2161
0
}
2162
2163
bool DomainParticipantImpl::MyRTPSParticipantListener::should_endpoints_match(
2164
        const RTPSParticipant*,
2165
        const SubscriptionBuiltinTopicData& reader_info,
2166
        const PublicationBuiltinTopicData& writer_info)
2167
0
{
2168
0
    Sentry sentinel(this);
2169
0
    if (sentinel)
2170
0
    {
2171
0
        DomainParticipantListener* listener = participant_->listener_;
2172
0
        if (nullptr != listener)
2173
0
        {
2174
0
            return listener->should_endpoints_match(participant_->participant_, reader_info, writer_info);
2175
0
        }
2176
0
    }
2177
2178
0
    return true;
2179
0
}
2180
2181
bool DomainParticipantImpl::new_remote_endpoint_discovered(
2182
        const fastdds::rtps::GUID_t& partguid,
2183
        uint16_t endpointId,
2184
        EndpointKind_t kind)
2185
0
{
2186
0
    if (get_rtps_participant() != nullptr)
2187
0
    {
2188
0
        if (kind == fastdds::rtps::WRITER)
2189
0
        {
2190
0
            return get_rtps_participant()->newRemoteWriterDiscovered(partguid, static_cast<int16_t>(endpointId));
2191
0
        }
2192
0
        else
2193
0
        {
2194
0
            return get_rtps_participant()->newRemoteReaderDiscovered(partguid, static_cast<int16_t>(endpointId));
2195
0
        }
2196
0
    }
2197
2198
0
    return false;
2199
0
}
2200
2201
ResourceEvent& DomainParticipantImpl::get_resource_event() const
2202
0
{
2203
0
    assert(nullptr != get_rtps_participant());
2204
0
    return get_rtps_participant()->get_resource_event();
2205
0
}
2206
2207
ReturnCode_t DomainParticipantImpl::register_dynamic_type(
2208
        DynamicType::_ref_type dyn_type)
2209
0
{
2210
0
    TypeSupport type(new DynamicPubSubType(dyn_type));
2211
0
    return get_participant()->register_type(type);
2212
0
}
2213
2214
bool DomainParticipantImpl::has_active_entities()
2215
0
{
2216
0
    if (!publishers_.empty())
2217
0
    {
2218
0
        return true;
2219
0
    }
2220
0
    if (!subscribers_.empty())
2221
0
    {
2222
0
        return true;
2223
0
    }
2224
0
    if (!topics_.empty())
2225
0
    {
2226
0
        return true;
2227
0
    }
2228
0
    return false;
2229
0
}
2230
2231
bool DomainParticipantImpl::set_qos(
2232
        DomainParticipantQos& to,
2233
        const DomainParticipantQos& from,
2234
        bool first_time)
2235
0
{
2236
0
    bool qos_should_be_updated = false;
2237
2238
0
    if (!(to.entity_factory() == from.entity_factory()))
2239
0
    {
2240
0
        to.entity_factory() = from.entity_factory();
2241
0
    }
2242
0
    if (!(to.user_data() == from.user_data()))
2243
0
    {
2244
0
        to.user_data() = from.user_data();
2245
0
        if (!first_time)
2246
0
        {
2247
0
            qos_should_be_updated = true;
2248
0
        }
2249
0
    }
2250
0
    if (first_time && !(to.allocation() == from.allocation()))
2251
0
    {
2252
0
        to.allocation() = from.allocation();
2253
0
    }
2254
0
    if (first_time && (to.properties() != from.properties()))
2255
0
    {
2256
0
        to.properties() = from.properties();
2257
0
    }
2258
0
    if (!(to.wire_protocol() == from.wire_protocol()))
2259
0
    {
2260
0
        to.wire_protocol() = from.wire_protocol();
2261
0
        if (!first_time)
2262
0
        {
2263
0
            qos_should_be_updated = true;
2264
0
        }
2265
0
    }
2266
0
    if (first_time && !(to.transport() == from.transport()))
2267
0
    {
2268
0
        to.transport() = from.transport();
2269
0
    }
2270
0
    if (first_time && to.name() != from.name())
2271
0
    {
2272
0
        to.name() = from.name();
2273
0
    }
2274
2275
0
    return qos_should_be_updated;
2276
0
}
2277
2278
ReturnCode_t DomainParticipantImpl::check_qos(
2279
        const DomainParticipantQos& qos)
2280
0
{
2281
0
    ReturnCode_t ret_val = RETCODE_OK;
2282
2283
0
    if (qos.allocation().data_limits.max_user_data != 0 &&
2284
0
            qos.allocation().data_limits.max_user_data <= qos.user_data().getValue().size())
2285
0
    {
2286
0
        ret_val = RETCODE_INCONSISTENT_POLICY;
2287
0
    }
2288
2289
0
    if (RETCODE_OK == ret_val)
2290
0
    {
2291
        // Check participant's type propagation policy
2292
0
        using utils::to_type_propagation;
2293
0
        using utils::TypePropagation;
2294
2295
0
        auto type_propagation = to_type_propagation(qos.properties());
2296
2297
0
        if (TypePropagation::TYPEPROPAGATION_UNKNOWN == type_propagation)
2298
0
        {
2299
0
            EPROSIMA_LOG_ERROR(RTPS_QOS_CHECK, "Invalid value for property " << parameter_policy_type_propagation);
2300
0
            return RETCODE_INCONSISTENT_POLICY;
2301
0
        }
2302
0
    }
2303
2304
    // Check participant's wire protocol (builtin flow controller) configuration
2305
0
    if (RETCODE_OK == ret_val)
2306
0
    {
2307
0
        const std::string& builtin_flow_controller_name = qos.wire_protocol().builtin.flow_controller_name;
2308
2309
0
        if (!builtin_flow_controller_name.empty())
2310
0
        {
2311
            // Get the list of flow controllers
2312
0
            auto flow_controllers = qos.flow_controllers();
2313
2314
            // Check if any flow controller matches the builtin flow controller name
2315
0
            bool found = std::any_of(flow_controllers.begin(), flow_controllers.end(),
2316
0
                            [&builtin_flow_controller_name](const std::shared_ptr<fastdds::rtps::
2317
0
                                    FlowControllerDescriptor>& fc)
2318
0
                            {
2319
0
                                return fc && fc->name == builtin_flow_controller_name;
2320
0
                            });
2321
2322
0
            if (!found)
2323
0
            {
2324
0
                EPROSIMA_LOG_ERROR(RTPS_QOS_CHECK, "Flow controller name not found in flow controllers list");
2325
0
                return RETCODE_INCONSISTENT_POLICY;
2326
0
            }
2327
0
        }
2328
0
    }
2329
2330
2331
0
    return ret_val;
2332
0
}
2333
2334
bool DomainParticipantImpl::can_qos_be_updated(
2335
        const DomainParticipantQos& to,
2336
        const DomainParticipantQos& from)
2337
0
{
2338
0
    bool updatable = true;
2339
0
    if (!(to.allocation() == from.allocation()))
2340
0
    {
2341
0
        updatable = false;
2342
0
        EPROSIMA_LOG_WARNING(RTPS_QOS_CHECK,
2343
0
                "ParticipantResourceLimitsQos cannot be changed after the participant is enabled");
2344
0
    }
2345
0
    if ((to.properties() != from.properties()))
2346
0
    {
2347
0
        updatable = false;
2348
0
        EPROSIMA_LOG_WARNING(RTPS_QOS_CHECK, "PropertyPolicyQos cannot be changed after the participant is enabled");
2349
0
    }
2350
0
    if (!(to.wire_protocol() == from.wire_protocol()))
2351
0
    {
2352
        // Check that the only modification was in wire_protocol().discovery_config.m_DiscoveryServers
2353
0
        if ((to.wire_protocol().builtin.discovery_config.m_DiscoveryServers ==
2354
0
                from.wire_protocol().builtin.discovery_config.m_DiscoveryServers) ||
2355
0
                (!(to.wire_protocol().builtin.discovery_config.m_DiscoveryServers ==
2356
0
                from.wire_protocol().builtin.discovery_config.m_DiscoveryServers) &&
2357
0
                (!(to.wire_protocol().prefix == from.wire_protocol().prefix) ||
2358
0
                !(to.wire_protocol().participant_id == from.wire_protocol().participant_id) ||
2359
0
                !(to.wire_protocol().port == from.wire_protocol().port) ||
2360
0
                !(to.wire_protocol().default_unicast_locator_list ==
2361
0
                from.wire_protocol().default_unicast_locator_list) ||
2362
0
                !(to.wire_protocol().default_multicast_locator_list ==
2363
0
                from.wire_protocol().default_multicast_locator_list) ||
2364
0
                !(to.wire_protocol().default_external_unicast_locators ==
2365
0
                from.wire_protocol().default_external_unicast_locators) ||
2366
0
                !(to.wire_protocol().ignore_non_matching_locators ==
2367
0
                from.wire_protocol().ignore_non_matching_locators) ||
2368
0
                !(to.wire_protocol().builtin.use_WriterLivelinessProtocol ==
2369
0
                from.wire_protocol().builtin.use_WriterLivelinessProtocol) ||
2370
0
                !(to.wire_protocol().builtin.network_configuration ==
2371
0
                from.wire_protocol().builtin.network_configuration) ||
2372
0
                !(to.wire_protocol().builtin.metatrafficUnicastLocatorList ==
2373
0
                from.wire_protocol().builtin.metatrafficUnicastLocatorList) ||
2374
0
                !(to.wire_protocol().builtin.metatrafficMulticastLocatorList ==
2375
0
                from.wire_protocol().builtin.metatrafficMulticastLocatorList) ||
2376
0
                !(to.wire_protocol().builtin.metatraffic_external_unicast_locators ==
2377
0
                from.wire_protocol().builtin.metatraffic_external_unicast_locators) ||
2378
0
                !(to.wire_protocol().builtin.initialPeersList == from.wire_protocol().builtin.initialPeersList) ||
2379
0
                !(to.wire_protocol().builtin.readerHistoryMemoryPolicy ==
2380
0
                from.wire_protocol().builtin.readerHistoryMemoryPolicy) ||
2381
0
                !(to.wire_protocol().builtin.readerPayloadSize == from.wire_protocol().builtin.readerPayloadSize) ||
2382
0
                !(to.wire_protocol().builtin.writerHistoryMemoryPolicy ==
2383
0
                from.wire_protocol().builtin.writerHistoryMemoryPolicy) ||
2384
0
                !(to.wire_protocol().builtin.writerPayloadSize == from.wire_protocol().builtin.writerPayloadSize) ||
2385
0
                !(to.wire_protocol().builtin.mutation_tries == from.wire_protocol().builtin.mutation_tries) ||
2386
0
                !(to.wire_protocol().builtin.flow_controller_name ==
2387
0
                from.wire_protocol().builtin.flow_controller_name) ||
2388
0
                !(to.wire_protocol().builtin.avoid_builtin_multicast ==
2389
0
                from.wire_protocol().builtin.avoid_builtin_multicast) ||
2390
0
                !(to.wire_protocol().builtin.discovery_config.discoveryProtocol ==
2391
0
                from.wire_protocol().builtin.discovery_config.discoveryProtocol) ||
2392
0
                !(to.wire_protocol().builtin.discovery_config.use_SIMPLE_EndpointDiscoveryProtocol ==
2393
0
                from.wire_protocol().builtin.discovery_config.use_SIMPLE_EndpointDiscoveryProtocol) ||
2394
0
                !(to.wire_protocol().builtin.discovery_config.use_STATIC_EndpointDiscoveryProtocol ==
2395
0
                from.wire_protocol().builtin.discovery_config.use_STATIC_EndpointDiscoveryProtocol) ||
2396
0
                !(to.wire_protocol().builtin.discovery_config.discoveryServer_client_syncperiod ==
2397
0
                from.wire_protocol().builtin.discovery_config.discoveryServer_client_syncperiod) ||
2398
0
                !(to.wire_protocol().builtin.discovery_config.m_PDPfactory ==
2399
0
                from.wire_protocol().builtin.discovery_config.m_PDPfactory) ||
2400
0
                !(to.wire_protocol().builtin.discovery_config.leaseDuration ==
2401
0
                from.wire_protocol().builtin.discovery_config.leaseDuration) ||
2402
0
                !(to.wire_protocol().builtin.discovery_config.leaseDuration_announcementperiod ==
2403
0
                from.wire_protocol().builtin.discovery_config.leaseDuration_announcementperiod) ||
2404
0
                !(to.wire_protocol().builtin.discovery_config.initial_announcements ==
2405
0
                from.wire_protocol().builtin.discovery_config.initial_announcements) ||
2406
0
                !(to.wire_protocol().builtin.discovery_config.m_simpleEDP ==
2407
0
                from.wire_protocol().builtin.discovery_config.m_simpleEDP) ||
2408
0
                !(strcmp(to.wire_protocol().builtin.discovery_config.static_edp_xml_config(),
2409
0
                from.wire_protocol().builtin.discovery_config.static_edp_xml_config()) == 0) ||
2410
0
                !(to.wire_protocol().builtin.discovery_config.ignoreParticipantFlags ==
2411
0
                from.wire_protocol().builtin.discovery_config.ignoreParticipantFlags))))
2412
0
        {
2413
0
            updatable = false;
2414
0
            EPROSIMA_LOG_WARNING(RTPS_QOS_CHECK,
2415
0
                    "WireProtocolConfigQos cannot be changed after the participant is enabled, "
2416
0
                    << "with the exception of builtin.discovery_config.m_DiscoveryServers");
2417
0
        }
2418
0
    }
2419
0
    if (!(to.transport() == from.transport()))
2420
0
    {
2421
0
        updatable = false;
2422
0
        EPROSIMA_LOG_WARNING(RTPS_QOS_CHECK, "TransportConfigQos cannot be changed after the participant is enabled");
2423
0
    }
2424
0
    if (!(to.name() == from.name()))
2425
0
    {
2426
0
        updatable = false;
2427
0
        EPROSIMA_LOG_WARNING(RTPS_QOS_CHECK, "Participant name cannot be changed after the participant is enabled");
2428
0
    }
2429
0
    if (!(to.builtin_controllers_sender_thread() == from.builtin_controllers_sender_thread()))
2430
0
    {
2431
0
        updatable = false;
2432
0
        EPROSIMA_LOG_WARNING(RTPS_QOS_CHECK,
2433
0
                "Participant builtin_controllers_sender_thread cannot be changed after the participant is enabled");
2434
0
    }
2435
0
    if (!(to.timed_events_thread() == from.timed_events_thread()))
2436
0
    {
2437
0
        updatable = false;
2438
0
        EPROSIMA_LOG_WARNING(RTPS_QOS_CHECK,
2439
0
                "Participant timed_events_thread cannot be changed after the participant is enabled");
2440
0
    }
2441
0
    if (!(to.discovery_server_thread() == from.discovery_server_thread()))
2442
0
    {
2443
0
        updatable = false;
2444
0
        EPROSIMA_LOG_WARNING(RTPS_QOS_CHECK,
2445
0
                "Participant discovery_server_thread cannot be changed after the participant is enabled");
2446
0
    }
2447
0
    if (!(to.typelookup_service_thread() == from.typelookup_service_thread()))
2448
0
    {
2449
0
        updatable = false;
2450
0
        EPROSIMA_LOG_WARNING(RTPS_QOS_CHECK,
2451
0
                "Participant typelookup_service_thread cannot be changed after the participant is enabled");
2452
0
    }
2453
#if HAVE_SECURITY
2454
    if (!(to.security_log_thread() == from.security_log_thread()))
2455
    {
2456
        updatable = false;
2457
        EPROSIMA_LOG_WARNING(RTPS_QOS_CHECK,
2458
                "Participant security_log_thread cannot be changed after the participant is enabled");
2459
    }
2460
#endif // if HAVE_SECURITY
2461
0
    return updatable;
2462
0
}
2463
2464
void DomainParticipantImpl::create_instance_handle(
2465
        InstanceHandle_t& handle)
2466
0
{
2467
0
    using rtps::octet;
2468
2469
0
    uint32_t id = ++next_instance_id_;
2470
0
    handle = guid_;
2471
0
    handle.value[15] = 0x01; // Vendor specific;
2472
0
    handle.value[14] = static_cast<octet>(id & 0xFF);
2473
0
    handle.value[13] = static_cast<octet>((id >> 8) & 0xFF);
2474
0
    handle.value[12] = static_cast<octet>((id >> 16) & 0xFF);
2475
0
}
2476
2477
DomainParticipantListener* DomainParticipantImpl::get_listener_for(
2478
        const StatusMask& status)
2479
0
{
2480
0
    if (get_participant()->get_status_mask().is_active(status))
2481
0
    {
2482
0
        return get_listener();
2483
0
    }
2484
0
    return nullptr;
2485
0
}
2486
2487
bool DomainParticipantImpl::fill_type_information(
2488
        const TypeSupport& type,
2489
        xtypes::TypeInformationParameter& type_information)
2490
0
{
2491
0
    using utils::to_type_propagation;
2492
0
    using utils::TypePropagation;
2493
2494
0
    auto properties = qos_.properties();
2495
0
    auto type_propagation = to_type_propagation(properties);
2496
0
    bool should_assign_type_information =
2497
0
            (TypePropagation::TYPEPROPAGATION_ENABLED == type_propagation) ||
2498
0
            (TypePropagation::TYPEPROPAGATION_MINIMAL_BANDWIDTH == type_propagation);
2499
2500
0
    if (should_assign_type_information && (xtypes::TK_NONE != type->type_identifiers().type_identifier1()._d()))
2501
0
    {
2502
0
        xtypes::TypeInformation type_info;
2503
2504
0
        if (RETCODE_OK ==
2505
0
                fastdds::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer().get_type_information(
2506
0
                    type->type_identifiers(), type_info))
2507
0
        {
2508
0
            switch (type_propagation)
2509
0
            {
2510
0
                case TypePropagation::TYPEPROPAGATION_ENABLED:
2511
0
                {
2512
                    // Use both complete and minimal type information
2513
0
                    type_information.type_information = type_info;
2514
0
                    break;
2515
0
                }
2516
0
                case TypePropagation::TYPEPROPAGATION_MINIMAL_BANDWIDTH:
2517
0
                {
2518
                    // Use minimal type information only
2519
0
                    type_information.type_information.minimal() = type_info.minimal();
2520
0
                    break;
2521
0
                }
2522
0
                default:
2523
                    // This should never happen as other cases are protected by should_assign_type_information
2524
0
                    assert(false);
2525
0
                    break;
2526
0
            }
2527
2528
0
            type_information.assigned(true);
2529
0
            return true;
2530
0
        }
2531
0
    }
2532
2533
0
    return false;
2534
0
}
2535
2536
}  // namespace dds
2537
}  // namespace fastdds
2538
}  // namespace eprosima