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/xmlparser/XMLParser.cpp
Line
Count
Source
1
// Copyright 2017 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
#include <xmlparser/XMLParser.h>
16
17
#include <cstdint>
18
#include <cstdlib>
19
#include <iostream>
20
#include <memory>
21
#include <string>
22
#include <unordered_map>
23
#ifdef _WIN32
24
#include <windows.h>
25
#else
26
#include <unistd.h>
27
#endif // _WIN32
28
29
#include <tinyxml2.h>
30
31
#include <fastdds/dds/log/FileConsumer.hpp>
32
#include <fastdds/dds/log/StdoutConsumer.hpp>
33
#include <fastdds/dds/log/StdoutErrConsumer.hpp>
34
#include <fastdds/LibrarySettings.hpp>
35
#include <fastdds/rtps/attributes/ThreadSettings.hpp>
36
#include <fastdds/rtps/transport/network/NetmaskFilterKind.hpp>
37
#include <fastdds/rtps/transport/shared_mem/SharedMemTransportDescriptor.hpp>
38
#include <fastdds/rtps/transport/PortBasedTransportDescriptor.hpp>
39
#include <fastdds/rtps/transport/SocketTransportDescriptor.hpp>
40
#include <fastdds/rtps/transport/TCPTransportDescriptor.hpp>
41
#include <fastdds/rtps/transport/TCPv4TransportDescriptor.hpp>
42
#include <fastdds/rtps/transport/UDPTransportDescriptor.hpp>
43
44
#include <rtps/network/utils/netmask_filter.hpp>
45
#include <xmlparser/XMLParserUtils.hpp>
46
#include <xmlparser/XMLParserCommon.h>
47
#include <xmlparser/XMLParserUtils.hpp>
48
#include <xmlparser/XMLProfileManager.h>
49
#include <xmlparser/XMLTree.h>
50
51
namespace eprosima {
52
namespace fastdds {
53
namespace xmlparser {
54
55
using namespace eprosima::fastdds::xml::detail;
56
57
XMLP_ret XMLParser::loadDefaultXMLFile(
58
        up_base_node_t& root)
59
0
{
60
    // Use absolute path to ensure that the file is loaded only once
61
#ifdef _WIN32
62
    char current_directory[MAX_PATH];
63
    if (GetCurrentDirectory(MAX_PATH, current_directory) == 0)
64
    {
65
        EPROSIMA_LOG_ERROR(XMLPARSER, "GetCurrentDirectory failed " << GetLastError());
66
    }
67
    else
68
    {
69
        strcat_s(current_directory, MAX_PATH, DEFAULT_FASTDDS_PROFILES);
70
        return loadXML(current_directory, root, true);
71
    }
72
#else
73
0
    char current_directory[PATH_MAX];
74
0
    if (getcwd(current_directory, PATH_MAX) == NULL)
75
0
    {
76
0
        EPROSIMA_LOG_ERROR(XMLPARSER, "getcwd failed " << std::strerror(errno));
77
0
    }
78
0
    else
79
0
    {
80
0
        strcat(current_directory, "/");
81
0
        strcat(current_directory, DEFAULT_FASTDDS_PROFILES);
82
0
        return loadXML(current_directory, root, true);
83
0
    }
84
0
#endif // _WIN32
85
0
    return XMLP_ret::XML_ERROR;
86
0
}
87
88
XMLP_ret XMLParser::parseXML(
89
        tinyxml2::XMLDocument& xmlDoc,
90
        up_base_node_t& root)
91
22.1k
{
92
22.1k
    XMLP_ret ret = XMLP_ret::XML_OK;
93
22.1k
    tinyxml2::XMLElement* p_root = xmlDoc.FirstChildElement(ROOT);
94
22.1k
    if (nullptr == p_root)
95
16.5k
    {
96
        // Just profiles in the XML.
97
16.5k
        if (nullptr == (p_root = xmlDoc.FirstChildElement(PROFILES)))
98
2.30k
        {
99
            // Just types in the XML.
100
2.30k
            if (nullptr == (p_root = xmlDoc.FirstChildElement(TYPES)))
101
697
            {
102
                // Just log config in the XML.
103
697
                if (nullptr == (p_root = xmlDoc.FirstChildElement(LOG)))
104
32
                {
105
                    // Just library_settings config in the XML.
106
32
                    if (nullptr == (p_root = xmlDoc.FirstChildElement(LIBRARY_SETTINGS)))
107
31
                    {
108
31
                        EPROSIMA_LOG_ERROR(XMLPARSER, "Not found root tag");
109
31
                        ret = XMLP_ret::XML_ERROR;
110
31
                    }
111
1
                    else
112
1
                    {
113
1
                        root.reset(new BaseNode{NodeType::LIBRARY_SETTINGS});
114
1
                        ret  = parseXMLLibrarySettings(p_root);
115
1
                    }
116
32
                }
117
665
                else
118
665
                {
119
665
                    root.reset(new BaseNode{NodeType::LOG});
120
665
                    ret  = parseLogConfig(p_root);
121
665
                }
122
697
            }
123
1.60k
            else
124
1.60k
            {
125
1.60k
                root.reset(new BaseNode{ NodeType::TYPES });
126
1.60k
                ret = parseDynamicTypes(p_root);
127
1.60k
            }
128
2.30k
        }
129
14.2k
        else
130
14.2k
        {
131
14.2k
            root.reset(new BaseNode{ NodeType::PROFILES });
132
14.2k
            ret = parseProfiles(p_root, *root);
133
14.2k
        }
134
16.5k
    }
135
5.57k
    else
136
5.57k
    {
137
5.57k
        root.reset(new BaseNode{ NodeType::ROOT });
138
5.57k
        tinyxml2::XMLElement* node = p_root->FirstChildElement();
139
5.57k
        const char* tag = nullptr;
140
23.7k
        while ((nullptr != node) && (ret == XMLP_ret::XML_OK))
141
18.1k
        {
142
18.1k
            if (nullptr != (tag = node->Value()))
143
18.1k
            {
144
18.1k
                if (strcmp(tag, PROFILES) == 0)
145
1.91k
                {
146
1.91k
                    up_base_node_t profiles_node = up_base_node_t{ new BaseNode{NodeType::PROFILES} };
147
1.91k
                    if (XMLP_ret::XML_OK == (ret = parseProfiles(node, *profiles_node)))
148
1.88k
                    {
149
1.88k
                        root->addChild(std::move(profiles_node));
150
1.88k
                    }
151
1.91k
                }
152
16.2k
                else if (strcmp(tag, LIBRARY_SETTINGS) == 0)
153
1
                {
154
                    // TODO Workaround to propagate the return code upstream. A refactor is needed to propagate the
155
                    // return code in some other more sensible way or populate the object and change code upstream to
156
                    // read this new object.
157
1
                    up_base_node_t library_node = up_base_node_t{ new BaseNode{NodeType::LIBRARY_SETTINGS} };
158
1
                    if (XMLP_ret::XML_OK == (ret = parseXMLLibrarySettings(node)))
159
0
                    {
160
0
                        root->addChild(std::move(library_node));
161
0
                    }
162
1
                }
163
16.2k
                else if (strcmp(tag, DOMAINPARTICIPANT_FACTORY) == 0)
164
280
                {
165
280
                    ret = parseXMLDomainParticipantFactoryProf(node, *root);
166
280
                }
167
15.9k
                else if (strcmp(tag, PARTICIPANT) == 0)
168
700
                {
169
700
                    ret = parseXMLParticipantProf(node, *root);
170
700
                }
171
15.2k
                else if (strcmp(tag, PUBLISHER) == 0 || strcmp(tag, DATA_WRITER) == 0)
172
4.08k
                {
173
4.08k
                    ret = parseXMLPublisherProf(node, *root);
174
4.08k
                }
175
11.1k
                else if (strcmp(tag, SUBSCRIBER) == 0 || strcmp(tag, DATA_READER) == 0)
176
4.38k
                {
177
4.38k
                    ret = parseXMLSubscriberProf(node, *root);
178
4.38k
                }
179
6.76k
                else if (strcmp(tag, TOPIC) == 0)
180
1.56k
                {
181
1.56k
                    ret = parseXMLTopicData(node, *root);
182
1.56k
                }
183
5.20k
                else if (strcmp(tag, REQUESTER) == 0)
184
763
                {
185
763
                    ret = parseXMLRequesterProf(node, *root);
186
763
                }
187
4.43k
                else if (strcmp(tag, REPLIER) == 0)
188
405
                {
189
405
                    ret = parseXMLReplierProf(node, *root);
190
405
                }
191
4.03k
                else if (strcmp(tag, TYPES) == 0)
192
269
                {
193
                    // TODO Workaround to propagate the return code upstream. A refactor is needed to propagate the
194
                    // return code in some other more sensible way or populate the object and change code upstream to
195
                    // read this new object.
196
269
                    up_base_node_t types_node = up_base_node_t{ new BaseNode{NodeType::TYPES} };
197
269
                    if (XMLP_ret::XML_OK == (ret = parseXMLTypes(node)))
198
268
                    {
199
268
                        root->addChild(std::move(types_node));
200
268
                    }
201
269
                }
202
3.76k
                else if (strcmp(tag, LOG) == 0)
203
2.97k
                {
204
                    // TODO Workaround to propagate the return code upstream. A refactor is needed to propagate the
205
                    // return code in some other more sensible way or populate the object and change code upstream to
206
                    // read this new object.
207
2.97k
                    up_base_node_t log_node = up_base_node_t{ new BaseNode{NodeType::LOG} };
208
2.97k
                    if (XMLP_ret::XML_OK == (ret = parseLogConfig(node)))
209
2.96k
                    {
210
2.96k
                        root->addChild(std::move(log_node));
211
2.96k
                    }
212
2.97k
                }
213
785
                else
214
785
                {
215
785
                    EPROSIMA_LOG_ERROR(XMLPARSER, "Not expected tag: '" << tag << "'");
216
785
                    ret = XMLP_ret::XML_ERROR;
217
785
                }
218
18.1k
            }
219
220
18.1k
            node = node->NextSiblingElement();
221
18.1k
        }
222
5.57k
    }
223
22.1k
    return ret;
224
22.1k
}
225
226
XMLP_ret XMLParser::parseXMLProfiles(
227
        tinyxml2::XMLElement& profiles,
228
        up_base_node_t& root)
229
0
{
230
0
    XMLP_ret ret = XMLP_ret::XML_OK;
231
0
    root.reset(new BaseNode{NodeType::PROFILES});
232
0
    ret  = parseProfiles(&profiles, *root);
233
0
    return ret;
234
0
}
235
236
XMLP_ret XMLParser::parseXMLTransportsProf(
237
        tinyxml2::XMLElement* p_root)
238
241
{
239
    /*
240
        <xs:complexType name="TransportDescriptorListType">
241
            <xs:sequence>
242
                <xs:element name="transport_descriptor" type="rtpsTransportDescriptorType"/>
243
            </xs:sequence>
244
        </xs:complexType>
245
     */
246
247
241
    XMLP_ret ret = XMLP_ret::XML_OK;
248
241
    tinyxml2::XMLElement* p_element = p_root->FirstChildElement(TRANSPORT_DESCRIPTOR);
249
241
    while (p_element != nullptr)
250
0
    {
251
0
        ret = parseXMLTransportData(p_element);
252
0
        if (ret != XMLP_ret::XML_OK)
253
0
        {
254
0
            EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing transports");
255
0
            return ret;
256
0
        }
257
0
        p_element = p_element->NextSiblingElement(TRANSPORT_DESCRIPTOR);
258
0
    }
259
241
    return ret;
260
241
}
261
262
XMLP_ret XMLParser::parseXMLTransportData(
263
        tinyxml2::XMLElement* p_root)
264
0
{
265
    /*
266
        <xs:complexType name="rtpsTransportDescriptorType">
267
            <xs:all minOccurs="0">
268
                <xs:element name="transport_id" type="stringType"/>
269
                <xs:element name="type" type="stringType"/>
270
                <xs:element name="sendBufferSize" type="int32Type" minOccurs="0" maxOccurs="1"/>
271
                <xs:element name="receiveBufferSize" type="int32Type" minOccurs="0" maxOccurs="1"/>
272
                <xs:element name="TTL" type="uint8Type" minOccurs="0" maxOccurs="1"/>
273
                <xs:element name="non_blocking_send" type="boolType" minOccurs="0" maxOccurs="1"/>
274
                <xs:element name="maxMessageSize" type="uint32Type" minOccurs="0" maxOccurs="1"/>
275
                <xs:element name="maxInitialPeersRange" type="uint32Type" minOccurs="0" maxOccurs="1"/>
276
                <xs:element name="interfaceWhiteList" type="stringListType" minOccurs="0" maxOccurs="1"/>
277
                <xs:element name="wan_addr" type="stringType" minOccurs="0" maxOccurs="1"/>
278
                <xs:element name="output_port" type="uint16Type" minOccurs="0" maxOccurs="1"/>
279
                <xs:element name="keep_alive_frequency_ms" type="uint32Type" minOccurs="0" maxOccurs="1"/>
280
                <xs:element name="keep_alive_timeout_ms" type="uint32Type" minOccurs="0" maxOccurs="1"/>
281
                <xs:element name="max_logical_port" type="uint16Type" minOccurs="0" maxOccurs="1"/>
282
                <xs:element name="logical_port_range" type="uint16Type" minOccurs="0" maxOccurs="1"/>
283
                <xs:element name="logical_port_increment" type="uint16Type" minOccurs="0" maxOccurs="1"/>
284
                <xs:element name="metadata_logical_port" type="uint16Type" minOccurs="0" maxOccurs="1"/>
285
                <xs:element name="listening_ports" type="portListType" minOccurs="0" maxOccurs="1"/>
286
                <xs:element name="calculate_crc" type="boolType" minOccurs="0" maxOccurs="1"/>
287
                <xs:element name="check_crc" type="boolType" minOccurs="0" maxOccurs="1"/>
288
                <xs:element name="enable_tcp_nodelay" type="boolType" minOccurs="0" maxOccurs="1"/>
289
                <xs:element name="tcp_negotiation_timeout" type="uint32_t" minOccurs="0" maxOccurs="1"/>
290
                <xs:element name="tls" type="tlsConfigType" minOccurs="0" maxOccurs="1"/>
291
            </xs:all>
292
        </xs:complexType>
293
     */
294
295
0
    if (XMLP_ret::XML_OK != validateXMLTransportElements(*p_root))
296
0
    {
297
0
        return XMLP_ret::XML_ERROR;
298
0
    }
299
300
0
    tinyxml2::XMLElement* p_aux0 = nullptr;
301
0
    p_aux0 = p_root->FirstChildElement(TRANSPORT_ID);
302
0
    if (nullptr == p_aux0)
303
0
    {
304
0
        EPROSIMA_LOG_ERROR(XMLPARSER, "Not found '" << TRANSPORT_ID << "' attribute");
305
0
        return XMLP_ret::XML_ERROR;
306
0
    }
307
308
0
    XMLP_ret ret = XMLP_ret::XML_OK;
309
0
    sp_transport_t pDescriptor = nullptr;
310
311
0
    std::string sId = get_element_text(p_aux0);
312
0
    if (sId.empty())
313
0
    {
314
0
        EPROSIMA_LOG_ERROR(XMLPARSER, "'" << TRANSPORT_ID << "' attribute cannot be empty");
315
0
        return XMLP_ret::XML_ERROR;
316
0
    }
317
318
0
    p_aux0 = p_root->FirstChildElement(TYPE);
319
0
    if (nullptr == p_aux0)
320
0
    {
321
0
        EPROSIMA_LOG_ERROR(XMLPARSER, "Not found '" << TYPE << "' attribute");
322
0
        return XMLP_ret::XML_ERROR;
323
0
    }
324
325
0
    std::string sType = get_element_text(p_aux0);
326
0
    if (sType.empty())
327
0
    {
328
0
        EPROSIMA_LOG_ERROR(XMLPARSER, "'" << TYPE << "' attribute cannot be empty");
329
0
        return XMLP_ret::XML_ERROR;
330
0
    }
331
332
0
    ret = create_transport_descriptor_from_xml_type(p_root, sType, pDescriptor);
333
0
    if (ret != XMLP_ret::XML_OK)
334
0
    {
335
0
        return ret;
336
0
    }
337
338
0
    auto udp_descriptor = std::dynamic_pointer_cast<fastdds::rtps::UDPTransportDescriptor>(pDescriptor);
339
0
    auto tcp_descriptor = std::dynamic_pointer_cast<fastdds::rtps::TCPTransportDescriptor>(pDescriptor);
340
0
    auto shm_descriptor = std::dynamic_pointer_cast<fastdds::rtps::SharedMemTransportDescriptor>(pDescriptor);
341
0
    if (udp_descriptor)
342
0
    {
343
        // Output UDP Socket
344
0
        if (nullptr != (p_aux0 = p_root->FirstChildElement(UDP_OUTPUT_PORT)))
345
0
        {
346
0
            int iSocket = 0;
347
0
            if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iSocket, 0) || iSocket < 0 || iSocket > 65535)
348
0
            {
349
0
                return XMLP_ret::XML_ERROR;
350
0
            }
351
0
            udp_descriptor->m_output_udp_socket = static_cast<uint16_t>(iSocket);
352
0
        }
353
        // Non-blocking send
354
0
        if (nullptr != (p_aux0 = p_root->FirstChildElement(NON_BLOCKING_SEND)))
355
0
        {
356
0
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &udp_descriptor->non_blocking_send, 0))
357
0
            {
358
0
                return XMLP_ret::XML_ERROR;
359
0
            }
360
0
        }
361
0
    }
362
0
    else if (tcp_descriptor)
363
0
    {
364
0
        ret = parseXMLCommonTCPTransportData(p_root, tcp_descriptor);
365
0
        if (ret != XMLP_ret::XML_OK)
366
0
        {
367
0
            return ret;
368
0
        }
369
370
0
        auto tcp4_descriptor = std::dynamic_pointer_cast<fastdds::rtps::TCPv4TransportDescriptor>(tcp_descriptor);
371
0
        if (tcp4_descriptor)
372
0
        {
373
            // Wan Address
374
0
            if (nullptr != (p_aux0 = p_root->FirstChildElement(TCP_WAN_ADDR)))
375
0
            {
376
0
                std::string s;
377
0
                if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, 0))
378
0
                {
379
0
                    return XMLP_ret::XML_ERROR;
380
0
                }
381
0
                tcp4_descriptor->set_WAN_address(s);
382
0
            }
383
0
        }
384
0
    }
385
0
    else if (shm_descriptor)
386
0
    {
387
0
        ret = parseXMLCommonSharedMemTransportData(p_root, shm_descriptor);
388
0
        if (ret != XMLP_ret::XML_OK)
389
0
        {
390
0
            return ret;
391
0
        }
392
0
    }
393
394
0
    ret = parseXMLCommonTransportData(p_root, pDescriptor);
395
0
    if (ret != XMLP_ret::XML_OK)
396
0
    {
397
0
        return ret;
398
0
    }
399
400
0
    auto port_based_descriptor = std::dynamic_pointer_cast<fastdds::rtps::PortBasedTransportDescriptor>(pDescriptor);
401
0
    if (port_based_descriptor)
402
0
    {
403
0
        ret = parseXMLPortBasedTransportData(p_root, port_based_descriptor);
404
0
        if (ret != XMLP_ret::XML_OK)
405
0
        {
406
0
            return ret;
407
0
        }
408
0
    }
409
410
0
    auto socket_descriptor = std::dynamic_pointer_cast<fastdds::rtps::SocketTransportDescriptor>(pDescriptor);
411
0
    if (socket_descriptor)
412
0
    {
413
0
        ret = parseXMLSocketTransportData(p_root, socket_descriptor);
414
0
        if (ret != XMLP_ret::XML_OK)
415
0
        {
416
0
            return ret;
417
0
        }
418
0
    }
419
420
0
    XMLProfileManager::insertTransportById(sId, pDescriptor);
421
0
    return ret;
422
0
}
423
424
XMLP_ret XMLParser::validateXMLTransportElements(
425
        tinyxml2::XMLElement& p_root)
426
0
{
427
0
    XMLP_ret ret = XMLP_ret::XML_OK;
428
0
    for (tinyxml2::XMLElement* p_aux0 = p_root.FirstChildElement(); p_aux0 != nullptr;
429
0
            p_aux0 = p_aux0->NextSiblingElement())
430
0
    {
431
0
        const char* name = p_aux0->Name();
432
0
        if (!(strcmp(name, TRANSPORT_ID) == 0 ||
433
0
                strcmp(name, TYPE) == 0 ||
434
0
                strcmp(name, SEND_BUFFER_SIZE) == 0 ||
435
0
                strcmp(name, RECEIVE_BUFFER_SIZE) == 0 ||
436
0
                strcmp(name, MAX_MESSAGE_SIZE) == 0 ||
437
0
                strcmp(name, MAX_INITIAL_PEERS_RANGE) == 0 ||
438
0
                strcmp(name, WHITE_LIST) == 0 ||
439
0
                strcmp(name, NETMASK_FILTER) == 0 ||
440
0
                strcmp(name, NETWORK_INTERFACES) == 0 ||
441
0
                strcmp(name, TTL) == 0 ||
442
0
                strcmp(name, NON_BLOCKING_SEND) == 0 ||
443
0
                strcmp(name, UDP_OUTPUT_PORT) == 0 ||
444
0
                strcmp(name, UDP_PRIORITY_MAPPINGS) == 0 ||
445
0
                strcmp(name, TCP_WAN_ADDR) == 0 ||
446
0
                strcmp(name, KEEP_ALIVE_FREQUENCY) == 0 ||
447
0
                strcmp(name, KEEP_ALIVE_TIMEOUT) == 0 ||
448
0
                strcmp(name, MAX_LOGICAL_PORT) == 0 ||
449
0
                strcmp(name, LOGICAL_PORT_RANGE) == 0 ||
450
0
                strcmp(name, LOGICAL_PORT_INCREMENT) == 0 ||
451
0
                strcmp(name, LISTENING_PORTS) == 0 ||
452
0
                strcmp(name, CALCULATE_CRC) == 0 ||
453
0
                strcmp(name, CHECK_CRC) == 0 ||
454
0
                strcmp(name, KEEP_ALIVE_THREAD) == 0 ||
455
0
                strcmp(name, ACCEPT_THREAD) == 0 ||
456
0
                strcmp(name, ENABLE_TCP_NODELAY) == 0 ||
457
0
                strcmp(name, TCP_NEGOTIATION_TIMEOUT) == 0 ||
458
0
                strcmp(name, TLS) == 0 ||
459
0
                strcmp(name, SEGMENT_SIZE) == 0 ||
460
0
                strcmp(name, PORT_QUEUE_CAPACITY) == 0 ||
461
0
                strcmp(name, HEALTHY_CHECK_TIMEOUT_MS) == 0 ||
462
0
                strcmp(name, RTPS_DUMP_FILE) == 0 ||
463
0
                strcmp(name, DEFAULT_RECEPTION_THREADS) == 0 ||
464
0
                strcmp(name, RECEPTION_THREADS) == 0 ||
465
0
                strcmp(name, DUMP_THREAD) == 0 ||
466
0
                strcmp(name, PORT_OVERFLOW_POLICY) == 0 ||
467
0
                strcmp(name, SEGMENT_OVERFLOW_POLICY) == 0 ||
468
0
                strcmp(name, ETH_INTERFACE_NAME) == 0 ||
469
0
                strcmp(name, ETH_OUTPUT_PORT) == 0 ||
470
0
                strcmp(name, ETH_PRIORITY_MAPPINGS) == 0 ||
471
0
                strcmp(name, LOW_LEVEL_TRANSPORT) == 0
472
0
                ))
473
0
        {
474
0
            EPROSIMA_LOG_ERROR(XMLPARSER, "Invalid element found into 'transportDescriptorType'. Name: " << name);
475
0
            ret = XMLP_ret::XML_ERROR;
476
0
        }
477
0
    }
478
479
0
    return ret;
480
0
}
481
482
XMLP_ret XMLParser::parseXMLCommonTransportData(
483
        tinyxml2::XMLElement* p_root,
484
        sp_transport_t p_transport)
485
0
{
486
    /*
487
        <xs:complexType name="rtpsTransportDescriptorType">
488
            <xs:all minOccurs="0">
489
                <xs:element name="transport_id" type="stringType"/>
490
                <xs:element name="type" type="stringType"/>
491
                <xs:element name="maxMessageSize" type="uint32Type" minOccurs="0" maxOccurs="1"/>
492
                <xs:element name="maxInitialPeersRange" type="uint32Type" minOccurs="0" maxOccurs="1"/>
493
            </xs:all>
494
        </xs:complexType>
495
     */
496
0
    tinyxml2::XMLElement* p_aux0 = nullptr;
497
0
    const char* name = nullptr;
498
0
    for (p_aux0 = p_root->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
499
0
    {
500
0
        name = p_aux0->Name();
501
0
        if (strcmp(name, MAX_MESSAGE_SIZE) == 0)
502
0
        {
503
            // maxMessageSize - uint32Type
504
0
            uint32_t uSize = 0;
505
0
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &uSize, 0))
506
0
            {
507
0
                return XMLP_ret::XML_ERROR;
508
0
            }
509
0
            p_transport->maxMessageSize = uSize;
510
0
        }
511
0
        else if (strcmp(name, MAX_INITIAL_PEERS_RANGE) == 0)
512
0
        {
513
            // maxInitialPeersRange - uint32Type
514
0
            uint32_t uRange = 0;
515
0
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &uRange, 0))
516
0
            {
517
0
                return XMLP_ret::XML_ERROR;
518
0
            }
519
0
            p_transport->maxInitialPeersRange = uRange;
520
0
        }
521
0
    }
522
0
    return XMLP_ret::XML_OK;
523
0
}
524
525
XMLP_ret XMLParser::parseXMLPortBasedTransportData(
526
        tinyxml2::XMLElement* p_root,
527
        std::shared_ptr<fastdds::rtps::PortBasedTransportDescriptor> p_transport)
528
0
{
529
    /*
530
        <xs:complexType name="rtpsTransportDescriptorType">
531
            <xs:all minOccurs="0">
532
                <xs:element name="default_reception_threads" type="threadSettingsType" minOccurs="0" maxOccurs="1"/>
533
                <xs:element name="reception_threads" type="receptionThreadsListType" minOccurs="0" maxOccurs="1"/>
534
            </xs:all>
535
        </xs:complexType>
536
     */
537
0
    tinyxml2::XMLElement* p_aux0 = nullptr;
538
0
    const char* name = nullptr;
539
0
    for (p_aux0 = p_root->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
540
0
    {
541
0
        name = p_aux0->Name();
542
0
        if (strcmp(name, DEFAULT_RECEPTION_THREADS) == 0)
543
0
        {
544
0
            fastdds::rtps::ThreadSettings thread_settings;
545
0
            if (getXMLThreadSettings(*p_aux0, thread_settings) == XMLP_ret::XML_OK)
546
0
            {
547
0
                p_transport->default_reception_threads(thread_settings);
548
0
            }
549
0
            else
550
0
            {
551
0
                EPROSIMA_LOG_ERROR(XMLPARSER, "Incorrect thread settings");
552
0
                return XMLP_ret::XML_ERROR;
553
0
            }
554
0
        }
555
0
        else if (strcmp(name, RECEPTION_THREADS) == 0)
556
0
        {
557
0
            fastdds::rtps::PortBasedTransportDescriptor::ReceptionThreadsConfigMap reception_threads;
558
0
            if (parseXMLReceptionThreads(*p_aux0, reception_threads) == XMLP_ret::XML_OK)
559
0
            {
560
0
                p_transport->reception_threads(reception_threads);
561
0
            }
562
0
            else
563
0
            {
564
0
                EPROSIMA_LOG_ERROR(XMLPARSER, "Incorrect thread settings");
565
0
                return XMLP_ret::XML_ERROR;
566
0
            }
567
0
        }
568
0
    }
569
0
    return XMLP_ret::XML_OK;
570
0
}
571
572
XMLP_ret XMLParser::parseXMLSocketTransportData(
573
        tinyxml2::XMLElement* p_root,
574
        std::shared_ptr<fastdds::rtps::SocketTransportDescriptor> p_transport)
575
0
{
576
    /*
577
        <xs:complexType name="rtpsTransportDescriptorType">
578
            <xs:all minOccurs="0">
579
                <xs:element name="sendBufferSize" type="int32Type" minOccurs="0" maxOccurs="1"/>
580
                <xs:element name="receiveBufferSize" type="int32Type" minOccurs="0" maxOccurs="1"/>
581
                <xs:element name="TTL" type="uint8Type" minOccurs="0" maxOccurs="1"/>
582
                <xs:element name="interfaceWhiteList" type="addressListType" minOccurs="0" maxOccurs="1"/>
583
                <xs:element name="netmask_filter" type="netmaskFilterType" minOccurs="0" maxOccurs="1"/>
584
                <xs:element name="interfaces" type="interfacesType" minOccurs="0" maxOccurs="1"/>
585
            </xs:all>
586
        </xs:complexType>
587
     */
588
0
    tinyxml2::XMLElement* p_aux0 = nullptr;
589
0
    const char* name = nullptr;
590
0
    for (p_aux0 = p_root->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
591
0
    {
592
0
        name = p_aux0->Name();
593
0
        if (strcmp(name, SEND_BUFFER_SIZE) == 0)
594
0
        {
595
            // sendBufferSize - int32Type
596
0
            uint32_t iSize = 0;
597
0
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &iSize, 0))
598
0
            {
599
0
                return XMLP_ret::XML_ERROR;
600
0
            }
601
0
            p_transport->sendBufferSize = iSize;
602
0
        }
603
0
        else if (strcmp(name, RECEIVE_BUFFER_SIZE) == 0)
604
0
        {
605
            // receiveBufferSize - int32Type
606
0
            uint32_t iSize = 0;
607
0
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &iSize, 0))
608
0
            {
609
0
                return XMLP_ret::XML_ERROR;
610
0
            }
611
0
            p_transport->receiveBufferSize = iSize;
612
0
        }
613
0
        else if (strcmp(name, TTL) == 0)
614
0
        {
615
            // TTL - int8Type
616
0
            int iTTL = 0;
617
0
            if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iTTL, 0) || iTTL < 0 || iTTL > 255)
618
0
            {
619
0
                return XMLP_ret::XML_ERROR;
620
0
            }
621
0
            p_transport->TTL = static_cast<uint8_t>(iTTL);
622
0
        }
623
0
        else if (strcmp(name, WHITE_LIST) == 0)
624
0
        {
625
            // InterfaceWhiteList addressListType
626
0
            const char* address = nullptr;
627
0
            for (tinyxml2::XMLElement* p_aux1 = p_aux0->FirstChildElement();
628
0
                    p_aux1 != nullptr; p_aux1 = p_aux1->NextSiblingElement())
629
0
            {
630
0
                address = p_aux1->Name();
631
0
                if (strcmp(address, ADDRESS) == 0 || strcmp(address, NETWORK_INTERFACE) == 0)
632
0
                {
633
0
                    std::string text = get_element_text(p_aux1);
634
0
                    if (!text.empty())
635
0
                    {
636
0
                        p_transport->interfaceWhiteList.emplace_back(text);
637
0
                    }
638
0
                }
639
0
                else
640
0
                {
641
0
                    EPROSIMA_LOG_ERROR(XMLPARSER, "Invalid element found into 'interfaceWhiteList'. Name: " << address);
642
0
                    return XMLP_ret::XML_ERROR;
643
0
                }
644
0
            }
645
0
        }
646
0
        else if (strcmp(name, NETMASK_FILTER) == 0)
647
0
        {
648
0
            std::string netmask_filter_str;
649
0
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &netmask_filter_str, 0))
650
0
            {
651
0
                EPROSIMA_LOG_ERROR(XMLPARSER, "Invalid element found into 'netmask_filter'.");
652
0
                return XMLP_ret::XML_ERROR;
653
0
            }
654
655
0
            try
656
0
            {
657
0
                p_transport->netmask_filter = fastdds::rtps::network::netmask_filter::string_to_netmask_filter_kind(
658
0
                    netmask_filter_str);
659
0
            }
660
0
            catch (const std::invalid_argument& e)
661
0
            {
662
0
                EPROSIMA_LOG_ERROR(XMLPARSER, "Invalid element found into 'netmask_filter' : " << e.what());
663
0
                return XMLP_ret::XML_ERROR;
664
0
            }
665
0
        }
666
0
        else if (strcmp(name, NETWORK_INTERFACES) == 0)
667
0
        {
668
0
            if (XMLP_ret::XML_OK != parseXMLInterfaces(p_aux0, p_transport))
669
0
            {
670
0
                EPROSIMA_LOG_ERROR(XMLPARSER, "Failed to parse 'interfaces' element.");
671
0
                return XMLP_ret::XML_ERROR;
672
0
            }
673
0
        }
674
0
    }
675
0
    return XMLP_ret::XML_OK;
676
0
}
677
678
XMLP_ret XMLParser::parseXMLInterfaces(
679
        tinyxml2::XMLElement* p_root,
680
        std::shared_ptr<fastdds::rtps::SocketTransportDescriptor> p_transport)
681
0
{
682
    /*
683
        <xs:complexType name="interfacesType">
684
            <xs:all>
685
                <xs:element name="allowlist" type="allowlistType" minOccurs="0" maxOccurs="1"/>
686
                <xs:element name="blocklist" type="blocklistType" minOccurs="0" maxOccurs="1"/>
687
            </xs:all>
688
        </xs:complexType>
689
     */
690
0
    tinyxml2::XMLElement* p_aux0 = nullptr;
691
0
    const char* name = nullptr;
692
0
    for (p_aux0 = p_root->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
693
0
    {
694
0
        name = p_aux0->Name();
695
0
        if (strcmp(name, ALLOWLIST) == 0)
696
0
        {
697
0
            if (XMLP_ret::XML_OK != parseXMLAllowlist(p_aux0, p_transport))
698
0
            {
699
0
                EPROSIMA_LOG_ERROR(XMLPARSER, "Failed to parse 'allowlist'.");
700
0
                return XMLP_ret::XML_ERROR;
701
0
            }
702
0
        }
703
0
        else if (strcmp(name, BLOCKLIST) == 0)
704
0
        {
705
0
            if (XMLP_ret::XML_OK != parseXMLBlocklist(p_aux0, p_transport))
706
0
            {
707
0
                EPROSIMA_LOG_ERROR(XMLPARSER, "Failed to parse 'blocklist'.");
708
0
                return XMLP_ret::XML_ERROR;
709
0
            }
710
0
        }
711
0
        else
712
0
        {
713
0
            EPROSIMA_LOG_ERROR(XMLPARSER, "Invalid element found in 'interfaces'. Name: " << name);
714
0
            return XMLP_ret::XML_ERROR;
715
0
        }
716
0
    }
717
0
    return XMLP_ret::XML_OK;
718
0
}
719
720
XMLP_ret XMLParser::parseXMLAllowlist(
721
        tinyxml2::XMLElement* p_root,
722
        std::shared_ptr<fastdds::rtps::SocketTransportDescriptor> p_transport)
723
0
{
724
    /*
725
        <xs:complexType name="allowlistType">
726
            <xs:sequence minOccurs="0" maxOccurs="unbounded">
727
                <xs:element name="interface" minOccurs="0" maxOccurs="unbounded">
728
                    <xs:complexType>
729
                        <xs:attribute name="name" type="string" use="required"/>
730
                        <xs:attribute name="netmask_filter" type="netmaskFilterType" use="optional"/>
731
                    </xs:complexType>
732
                </xs:element>
733
            </xs:sequence>
734
        </xs:complexType>
735
     */
736
0
    static const char* INTERFACE_NAME = "interface";
737
0
    static const char* NAME_ATTR_NAME = "name";
738
0
    static const char* NETMASK_FILTER_ATTR_NAME = "netmask_filter";
739
740
0
    const tinyxml2::XMLElement* p_aux0 = nullptr;
741
0
    const char* name = nullptr;
742
0
    for (p_aux0 = p_root->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
743
0
    {
744
0
        name = p_aux0->Name();
745
0
        if (strcmp(name, INTERFACE_NAME) == 0)
746
0
        {
747
            // Parse interface name (device/ip)
748
0
            std::string iface_name;
749
0
            auto iface_name_attr = p_aux0->FindAttribute(NAME_ATTR_NAME);
750
0
            if (nullptr != iface_name_attr)
751
0
            {
752
0
                iface_name = iface_name_attr->Value();
753
0
                if (iface_name.empty())
754
0
                {
755
0
                    EPROSIMA_LOG_ERROR(XMLPARSER,
756
0
                            "Failed to parse 'allowlist' element. Attribute 'name' cannot be empty.");
757
0
                    return XMLP_ret::XML_ERROR;
758
0
                }
759
0
            }
760
0
            else
761
0
            {
762
0
                EPROSIMA_LOG_ERROR(XMLPARSER,
763
0
                        "Failed to parse 'allowlist' element. Required attribute 'name' not found.");
764
0
                return XMLP_ret::XML_ERROR;
765
0
            }
766
767
            // Parse netmask filter
768
0
            fastdds::rtps::NetmaskFilterKind netmask_filter{fastdds::rtps::NetmaskFilterKind::AUTO};
769
0
            auto netmask_filter_attr = p_aux0->FindAttribute(NETMASK_FILTER_ATTR_NAME);
770
0
            if (nullptr != netmask_filter_attr)
771
0
            {
772
0
                try
773
0
                {
774
0
                    netmask_filter = fastdds::rtps::network::netmask_filter::string_to_netmask_filter_kind(
775
0
                        netmask_filter_attr->Value());
776
0
                }
777
0
                catch (const std::invalid_argument& e)
778
0
                {
779
0
                    EPROSIMA_LOG_ERROR(XMLPARSER,
780
0
                            "Failed to parse 'allowlist' element. Invalid value found in 'netmask_filter' : "
781
0
                            << e.what());
782
0
                    return XMLP_ret::XML_ERROR;
783
0
                }
784
0
            }
785
            // Add valid item to allowlist
786
0
            p_transport->interface_allowlist.emplace_back(iface_name, netmask_filter);
787
0
        }
788
0
        else
789
0
        {
790
0
            EPROSIMA_LOG_ERROR(XMLPARSER, "Invalid element found in 'allowlist'. Name: " << name);
791
0
            return XMLP_ret::XML_ERROR;
792
0
        }
793
0
    }
794
0
    return XMLP_ret::XML_OK;
795
0
}
796
797
XMLP_ret XMLParser::parseXMLBlocklist(
798
        tinyxml2::XMLElement* p_root,
799
        std::shared_ptr<fastdds::rtps::SocketTransportDescriptor> p_transport)
800
0
{
801
    /*
802
        <xs:complexType name="blocklistType">
803
            <xs:sequence minOccurs="0" maxOccurs="unbounded">
804
                <xs:element name="interface" minOccurs="0" maxOccurs="unbounded">
805
                    <xs:complexType>
806
                        <xs:attribute name="name" type="string" use="required"/>
807
                    </xs:complexType>
808
                </xs:element>
809
            </xs:sequence>
810
       </xs:complexType>
811
     */
812
0
    static const char* INTERFACE_NAME = "interface";
813
0
    static const char* NAME_ATTR_NAME = "name";
814
815
0
    const tinyxml2::XMLElement* p_aux0 = nullptr;
816
0
    const char* name = nullptr;
817
0
    for (p_aux0 = p_root->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
818
0
    {
819
0
        name = p_aux0->Name();
820
0
        if (strcmp(name, INTERFACE_NAME) == 0)
821
0
        {
822
            // Parse interface name (device/ip)
823
0
            auto iface = p_aux0->FindAttribute(NAME_ATTR_NAME);
824
0
            if (nullptr != iface)
825
0
            {
826
0
                std::string iface_name = iface->Value();
827
0
                if (iface_name.empty())
828
0
                {
829
0
                    EPROSIMA_LOG_ERROR(XMLPARSER,
830
0
                            "Failed to parse 'blocklist' element. Attribute 'name' cannot be empty.");
831
0
                    return XMLP_ret::XML_ERROR;
832
0
                }
833
                // Add valid item to blocklist
834
0
                p_transport->interface_blocklist.emplace_back(iface_name);
835
0
            }
836
0
            else
837
0
            {
838
0
                EPROSIMA_LOG_ERROR(XMLPARSER,
839
0
                        "Failed to parse 'blocklist' element. Required attribute 'name' not found.");
840
0
                return XMLP_ret::XML_ERROR;
841
0
            }
842
0
        }
843
0
        else
844
0
        {
845
0
            EPROSIMA_LOG_ERROR(XMLPARSER, "Invalid element found in 'blocklist'. Name: " << name);
846
0
            return XMLP_ret::XML_ERROR;
847
0
        }
848
0
    }
849
0
    return XMLP_ret::XML_OK;
850
0
}
851
852
XMLP_ret XMLParser::parseXMLCommonTCPTransportData(
853
        tinyxml2::XMLElement* p_root,
854
        sp_transport_t p_transport)
855
0
{
856
    /*
857
        <xs:complexType name="rtpsTransportDescriptorType">
858
            <xs:all minOccurs="0">
859
                <xs:element name="keep_alive_frequency_ms" type="uint32Type"/>
860
                <xs:element name="keep_alive_timeout_ms" type="uint32Type"/>
861
                <xs:element name="max_logical_port" type="uint16Type"/>
862
                <xs:element name="logical_port_range" type="uint16Type"/>
863
                <xs:element name="logical_port_increment" type="uint16Type"/>
864
                <xs:element name="metadata_logical_port" type="uint16Type"/>
865
                <xs:element name="listening_ports" type="uint16ListType"/>
866
                <xs:sequence>
867
                    <xs:element name="port" type="uint16Type"/>
868
                </xs:sequence>
869
                <xs:element name="calculate_crc" type="boolType" minOccurs="0" maxOccurs="1"/>
870
                <xs:element name="check_crc" type="boolType" minOccurs="0" maxOccurs="1"/>
871
                <xs:element name="enable_tcp_nodelay" type="boolType" minOccurs="0" maxOccurs="1"/>
872
                <xs:element name="tls" type="tlsConfigType" minOccurs="0" maxOccurs="1"/>
873
                <xs:element name="keep_alive_thread" type="threadSettingsType" minOccurs="0" maxOccurs="1"/>
874
                <xs:element name="accept_thread" type="threadSettingsType" minOccurs="0" maxOccurs="1"/>
875
            </xs:all>
876
        </xs:complexType>
877
     */
878
879
0
    XMLP_ret ret = XMLP_ret::XML_OK;
880
0
    std::shared_ptr<fastdds::rtps::TCPTransportDescriptor> pTCPDesc =
881
0
            std::dynamic_pointer_cast<fastdds::rtps::TCPTransportDescriptor>(p_transport);
882
0
    if (pTCPDesc != nullptr)
883
0
    {
884
0
        tinyxml2::XMLElement* p_aux0 = nullptr;
885
0
        const char* name = nullptr;
886
0
        for (p_aux0 = p_root->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
887
0
        {
888
0
            name = p_aux0->Name();
889
0
            if (strcmp(name, KEEP_ALIVE_FREQUENCY) == 0)
890
0
            {
891
                // keep_alive_frequency_ms - uint32Type
892
0
                int iFrequency(0);
893
0
                if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iFrequency, 0))
894
0
                {
895
0
                    return XMLP_ret::XML_ERROR;
896
0
                }
897
0
                pTCPDesc->keep_alive_frequency_ms = static_cast<uint32_t>(iFrequency);
898
0
            }
899
0
            else if (strcmp(name, KEEP_ALIVE_TIMEOUT) == 0)
900
0
            {
901
                // keep_alive_timeout_ms - uint32Type
902
0
                int iTimeout(0);
903
0
                if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iTimeout, 0))
904
0
                {
905
0
                    return XMLP_ret::XML_ERROR;
906
0
                }
907
0
                pTCPDesc->keep_alive_timeout_ms = static_cast<uint32_t>(iTimeout);
908
0
            }
909
0
            else if (strcmp(name, MAX_LOGICAL_PORT) == 0)
910
0
            {
911
                // max_logical_port - uint16Type
912
0
                int iPort(0);
913
0
                if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iPort, 0) || iPort < 0 || iPort > 65535)
914
0
                {
915
0
                    return XMLP_ret::XML_ERROR;
916
0
                }
917
0
                pTCPDesc->max_logical_port = static_cast<uint16_t>(iPort);
918
0
            }
919
0
            else if (strcmp(name, LOGICAL_PORT_RANGE) == 0)
920
0
            {
921
                // logical_port_range - uint16Type
922
0
                int iPort(0);
923
0
                if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iPort, 0) || iPort < 0 || iPort > 65535)
924
0
                {
925
0
                    return XMLP_ret::XML_ERROR;
926
0
                }
927
0
                pTCPDesc->logical_port_range = static_cast<uint16_t>(iPort);
928
0
            }
929
0
            else if (strcmp(name, LOGICAL_PORT_INCREMENT) == 0)
930
0
            {
931
                // logical_port_increment - uint16Type
932
0
                int iPort(0);
933
0
                if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iPort, 0) || iPort < 0 || iPort > 65535)
934
0
                {
935
0
                    return XMLP_ret::XML_ERROR;
936
0
                }
937
0
                pTCPDesc->logical_port_increment = static_cast<uint16_t>(iPort);
938
0
            }
939
            // enable_tcp_nodelay - boolType
940
0
            else if (strcmp(name, ENABLE_TCP_NODELAY) == 0)
941
0
            {
942
0
                if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &pTCPDesc->enable_tcp_nodelay, 0))
943
0
                {
944
0
                    return XMLP_ret::XML_ERROR;
945
0
                }
946
0
            }
947
            // non_blocking_send - boolType
948
0
            else if (strcmp(name, NON_BLOCKING_SEND) == 0)
949
0
            {
950
0
                if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &pTCPDesc->non_blocking_send, 0))
951
0
                {
952
0
                    return XMLP_ret::XML_ERROR;
953
0
                }
954
0
            }
955
0
            else if (strcmp(name, LISTENING_PORTS) == 0)
956
0
            {
957
                // listening_ports uint16ListType
958
0
                tinyxml2::XMLElement* p_aux1 = p_aux0->FirstChildElement(PORT);
959
0
                while (nullptr != p_aux1)
960
0
                {
961
0
                    int iPort = 0;
962
0
                    if (XMLP_ret::XML_OK != getXMLInt(p_aux1, &iPort, 0) || iPort < 0 || iPort > 65535)
963
0
                    {
964
0
                        return XMLP_ret::XML_ERROR;
965
0
                    }
966
967
0
                    pTCPDesc->add_listener_port(static_cast<uint16_t>(iPort));
968
0
                    p_aux1 = p_aux1->NextSiblingElement(PORT);
969
0
                }
970
0
            }
971
0
            else if (strcmp(name, CALCULATE_CRC) == 0)
972
0
            {
973
0
                if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &pTCPDesc->calculate_crc, 0))
974
0
                {
975
0
                    return XMLP_ret::XML_ERROR;
976
0
                }
977
0
            }
978
0
            else if (strcmp(name, CHECK_CRC) == 0)
979
0
            {
980
0
                if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &pTCPDesc->check_crc, 0))
981
0
                {
982
0
                    return XMLP_ret::XML_ERROR;
983
0
                }
984
0
            }
985
0
            else if (strcmp(name, TLS) == 0)
986
0
            {
987
0
                if (XMLP_ret::XML_OK != parse_tls_config(p_aux0, p_transport))
988
0
                {
989
0
                    return XMLP_ret::XML_ERROR;
990
0
                }
991
0
            }
992
0
            else if (strcmp(name, KEEP_ALIVE_THREAD) == 0)
993
0
            {
994
0
                if (getXMLThreadSettings(*p_aux0, pTCPDesc->keep_alive_thread) != XMLP_ret::XML_OK)
995
0
                {
996
0
                    EPROSIMA_LOG_ERROR(XMLPARSER, "Incorrect thread settings");
997
0
                    return XMLP_ret::XML_ERROR;
998
0
                }
999
0
            }
1000
0
            else if (strcmp(name, ACCEPT_THREAD) == 0)
1001
0
            {
1002
0
                if (getXMLThreadSettings(*p_aux0, pTCPDesc->accept_thread) != XMLP_ret::XML_OK)
1003
0
                {
1004
0
                    EPROSIMA_LOG_ERROR(XMLPARSER, "Incorrect thread settings");
1005
0
                    return XMLP_ret::XML_ERROR;
1006
0
                }
1007
0
            }
1008
0
            else if (strcmp(name, TCP_NEGOTIATION_TIMEOUT) == 0)
1009
0
            {
1010
                // tcp_negotiation_timeout - uint32Type
1011
0
                int iTimeout(0);
1012
0
                if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iTimeout, 0))
1013
0
                {
1014
0
                    return XMLP_ret::XML_ERROR;
1015
0
                }
1016
0
                pTCPDesc->tcp_negotiation_timeout = static_cast<uint32_t>(iTimeout);
1017
0
            }
1018
0
        }
1019
0
    }
1020
0
    else
1021
0
    {
1022
0
        EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing TCP Transport data");
1023
0
        ret = XMLP_ret::XML_ERROR;
1024
0
    }
1025
1026
0
    return ret;
1027
0
}
1028
1029
XMLP_ret XMLParser::parseXMLCommonSharedMemTransportData(
1030
        tinyxml2::XMLElement* p_root,
1031
        sp_transport_t p_transport)
1032
0
{
1033
    /*
1034
        <xs:complexType name="rtpsTransportDescriptorType">
1035
            <xs:all minOccurs="0">
1036
                <xs:element name="maxMessageSize" type="uint32Type" minOccurs="0" maxOccurs="1"/>
1037
                <xs:element name="maxInitialPeersRange" type="uint32Type" minOccurs="0" maxOccurs="1"/>
1038
                <xs:element name="segment_size" type="uint32Type" minOccurs="0" maxOccurs="1"/>
1039
                <xs:element name="port_queue_capacity" type="uint32Type" minOccurs="0" maxOccurs="1"/>
1040
                <xs:element name="healthy_check_timeout_ms" type="uint32Type" minOccurs="0" maxOccurs="1"/>
1041
                <xs:element name="rtps_dump_file" type="stringType" minOccurs="0" maxOccurs="1"/>
1042
                <xs:element name="dump_thread" type="threadSettingsType" minOccurs="0" maxOccurs="1"/>
1043
            </xs:all>
1044
        </xs:complexType>
1045
     */
1046
1047
0
    XMLP_ret ret = XMLP_ret::XML_OK;
1048
0
    std::shared_ptr<fastdds::rtps::SharedMemTransportDescriptor> transport_descriptor =
1049
0
            std::dynamic_pointer_cast<fastdds::rtps::SharedMemTransportDescriptor>(p_transport);
1050
0
    if (transport_descriptor != nullptr)
1051
0
    {
1052
0
        tinyxml2::XMLElement* p_aux0 = nullptr;
1053
0
        const char* name = nullptr;
1054
0
        for (p_aux0 = p_root->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
1055
0
        {
1056
0
            uint32_t aux;
1057
0
            name = p_aux0->Name();
1058
0
            if (strcmp(name, SEGMENT_SIZE) == 0)
1059
0
            {
1060
0
                if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &aux, 0))
1061
0
                {
1062
0
                    return XMLP_ret::XML_ERROR;
1063
0
                }
1064
0
                transport_descriptor->segment_size(static_cast<uint32_t>(aux));
1065
0
            }
1066
0
            else if (strcmp(name, PORT_QUEUE_CAPACITY) == 0)
1067
0
            {
1068
0
                if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &aux, 0))
1069
0
                {
1070
0
                    return XMLP_ret::XML_ERROR;
1071
0
                }
1072
0
                transport_descriptor->port_queue_capacity(static_cast<uint32_t>(aux));
1073
0
            }
1074
0
            else if (strcmp(name, HEALTHY_CHECK_TIMEOUT_MS) == 0)
1075
0
            {
1076
0
                if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &aux, 0))
1077
0
                {
1078
0
                    return XMLP_ret::XML_ERROR;
1079
0
                }
1080
0
                transport_descriptor->healthy_check_timeout_ms(static_cast<uint32_t>(aux));
1081
0
            }
1082
0
            else if (strcmp(name, RTPS_DUMP_FILE) == 0)
1083
0
            {
1084
0
                std::string str;
1085
0
                if (XMLP_ret::XML_OK != getXMLString(p_aux0, &str, 0))
1086
0
                {
1087
0
                    return XMLP_ret::XML_ERROR;
1088
0
                }
1089
0
                transport_descriptor->rtps_dump_file(str);
1090
0
            }
1091
0
            else if (strcmp(name, DUMP_THREAD) == 0)
1092
0
            {
1093
0
                fastdds::rtps::ThreadSettings thread_settings;
1094
0
                if (getXMLThreadSettings(*p_aux0, thread_settings) != XMLP_ret::XML_OK)
1095
0
                {
1096
0
                    EPROSIMA_LOG_ERROR(XMLPARSER, "Incorrect thread settings");
1097
0
                    return XMLP_ret::XML_ERROR;
1098
0
                }
1099
0
                transport_descriptor->dump_thread(thread_settings);
1100
0
            }
1101
            // Do not parse nor fail on unkown tags; these may be parsed elsewhere
1102
0
        }
1103
0
    }
1104
0
    else
1105
0
    {
1106
0
        EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing SharedMem Transport data");
1107
0
        ret = XMLP_ret::XML_ERROR;
1108
0
    }
1109
1110
0
    return ret;
1111
0
}
1112
1113
XMLP_ret XMLParser::parse_tls_config(
1114
        tinyxml2::XMLElement* p_root,
1115
        sp_transport_t tcp_transport)
1116
0
{
1117
    /*
1118
        XSD:
1119
        <xs:simpleType name="tlsOptionsType">
1120
            <xs:restriction base="xs:string">
1121
                <xs:enumeration value="DEFAULT_WORKAROUNDS"/>
1122
                <xs:enumeration value="NO_COMPRESSION"/>
1123
                <xs:enumeration value="NO_SSLV2"/>
1124
                <xs:enumeration value="NO_SSLV3"/>
1125
                <xs:enumeration value="NO_TLSV1"/>
1126
                <xs:enumeration value="NO_TLSV1_1"/>
1127
                <xs:enumeration value="NO_TLSV1_2"/>
1128
                <xs:enumeration value="NO_TLSV1_3"/>
1129
                <xs:enumeration value="SINGLE_DH_USE"/>
1130
            </xs:restriction>
1131
        </xs:simpleType>
1132
1133
        <xs:complexType name="tlsOptionsVectorType">
1134
            <xs:sequence>
1135
                <xs:element name="option" type="tlsOptionsType" minOccurs="0" maxOccurs="unbounded"/>
1136
            </xs:sequence>
1137
        </xs:complexType>
1138
1139
        <xs:simpleType name="tlsVerifyModeType">
1140
            <xs:restriction base="xs:string">
1141
                <xs:enumeration value="VERIFY_NONE"/>
1142
                <xs:enumeration value="VERIFY_PEER"/>
1143
                <xs:enumeration value="VERIFY_FAIL_IF_NO_PEER_CERT"/>
1144
                <xs:enumeration value="VERIFY_CLIENT_ONCE"/>
1145
            </xs:restriction>
1146
        </xs:simpleType>
1147
1148
        <xs:complexType name="tlsVerifyModeVectorType">
1149
            <xs:sequence>
1150
                <xs:element name="verify" type="tlsVerifyModeType" minOccurs="0" maxOccurs="unbounded"/>
1151
            </xs:sequence>
1152
        </xs:complexType>
1153
1154
        <xs:complexType name="tlsConfigType">
1155
            <xs:all minOccurs="0">
1156
                <xs:element name="password" type="stringType" minOccurs="0" maxOccurs="1"/>
1157
                <xs:element name="options" type="tlsOptionsVectorType" minOccurs="0" maxOccurs="1"/>
1158
                <xs:element name="cert_chain_file" type="stringType" minOccurs="0" maxOccurs="1"/>
1159
                <xs:element name="private_key_file" type="stringType" minOccurs="0" maxOccurs="1"/>
1160
                <xs:element name="tmp_dh_file" type="stringType" minOccurs="0" maxOccurs="1"/>
1161
                <xs:element name="verify_file" type="stringType" minOccurs="0" maxOccurs="1"/>
1162
                <xs:element name="verify_mode" type="tlsVerifyModeVectorType" minOccurs="0" maxOccurs="1"/>
1163
                <xs:element name="verify_paths" type="tlsVerifyPathVectorType" minOccurs="0" maxOccurs="1"/>
1164
                <xs:element name="default_verify_path" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
1165
                <xs:element name="verify_depth" type="xs:int" minOccurs="0" maxOccurs="1"/>
1166
                <xs:element name="rsa_private_key_file" type="stringType" minOccurs="0" maxOccurs="1"/>
1167
            </xs:all>
1168
        </xs:complexType>
1169
1170
        XML Example:
1171
        <tls>
1172
            <password>Contraseña</password>
1173
            <private_key_file>Key_file.pem</private_key_file>
1174
            <cert_chain_file>Chain.pem</cert_chain_file>
1175
            <tmp_dh_file>DH.pem</tmp_dh_file>
1176
            <verify_file>verify.pem</verify_file>
1177
            <verify_mode>
1178
                <verify>VERIFY_PEER</verify>
1179
            </verify_mode>
1180
            <options>
1181
                <option>NO_TLSV1</option>
1182
                <option>NO_TLSV1_1</option>
1183
            </options>
1184
        </tls>
1185
     */
1186
0
    using namespace rtps;
1187
0
    using TCPDescriptor = std::shared_ptr<fastdds::rtps::TCPTransportDescriptor>;
1188
0
    using TLSVerifyMode = fastdds::rtps::TCPTransportDescriptor::TLSConfig::TLSVerifyMode;
1189
0
    using TLSOption = fastdds::rtps::TCPTransportDescriptor::TLSConfig::TLSOptions;
1190
0
    using TLSHandShakeMode = fastdds::rtps::TCPTransportDescriptor::TLSConfig::TLSHandShakeRole;
1191
1192
0
    XMLP_ret ret = XMLP_ret::XML_OK;
1193
1194
0
    TCPDescriptor pTCPDesc = std::dynamic_pointer_cast<fastdds::rtps::TCPTransportDescriptor>(tcp_transport);
1195
0
    pTCPDesc->apply_security = true;
1196
1197
0
    tinyxml2::XMLElement* p_aux0 = nullptr;
1198
1199
0
    for (p_aux0 = p_root->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
1200
0
    {
1201
0
        const std::string config = p_aux0->Value();
1202
0
        if (config.compare(TLS_PASSWORD) == 0)
1203
0
        {
1204
0
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &pTCPDesc->tls_config.password, 0))
1205
0
            {
1206
0
                ret = XMLP_ret::XML_ERROR;
1207
0
            }
1208
0
        }
1209
0
        else if (config.compare(TLS_PRIVATE_KEY_FILE) == 0)
1210
0
        {
1211
0
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &pTCPDesc->tls_config.private_key_file, 0))
1212
0
            {
1213
0
                ret = XMLP_ret::XML_ERROR;
1214
0
            }
1215
0
        }
1216
0
        else if (config.compare(TLS_CERT_CHAIN_FILE) == 0)
1217
0
        {
1218
0
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &pTCPDesc->tls_config.cert_chain_file, 0))
1219
0
            {
1220
0
                ret = XMLP_ret::XML_ERROR;
1221
0
            }
1222
0
        }
1223
0
        else if (config.compare(TLS_TMP_DH_FILE) == 0)
1224
0
        {
1225
0
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &pTCPDesc->tls_config.tmp_dh_file, 0))
1226
0
            {
1227
0
                ret = XMLP_ret::XML_ERROR;
1228
0
            }
1229
0
        }
1230
0
        else if (config.compare(TLS_VERIFY_FILE) == 0)
1231
0
        {
1232
0
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &pTCPDesc->tls_config.verify_file, 0))
1233
0
            {
1234
0
                ret = XMLP_ret::XML_ERROR;
1235
0
            }
1236
0
        }
1237
0
        else if (config.compare(TLS_VERIFY_PATHS) == 0)
1238
0
        {
1239
0
            tinyxml2::XMLElement* p_path = p_aux0->FirstChildElement();
1240
1241
0
            while (p_path != nullptr)
1242
0
            {
1243
0
                std::string type = p_path->Value();
1244
0
                if (type.compare(TLS_VERIFY_PATH) == 0)
1245
0
                {
1246
0
                    std::string path;
1247
1248
0
                    if (XMLP_ret::XML_OK != getXMLString(p_path, &path, 0))
1249
0
                    {
1250
0
                        ret = XMLP_ret::XML_ERROR;
1251
0
                    }
1252
0
                    else
1253
0
                    {
1254
0
                        pTCPDesc->tls_config.verify_paths.push_back(path);
1255
0
                    }
1256
1257
0
                    if (ret == XMLP_ret::XML_ERROR)
1258
0
                    {
1259
                        // Break while loop
1260
0
                        break;
1261
0
                    }
1262
0
                    p_path = p_path->NextSiblingElement();
1263
0
                }
1264
0
                else
1265
0
                {
1266
0
                    EPROSIMA_LOG_ERROR(XMLPARSER, "Unrecognized verify paths label: " << p_path->Value());
1267
0
                    ret = XMLP_ret::XML_ERROR;
1268
0
                    break;
1269
0
                }
1270
0
            }
1271
0
        }
1272
0
        else if (config.compare(TLS_VERIFY_DEPTH) == 0)
1273
0
        {
1274
0
            if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &pTCPDesc->tls_config.verify_depth, 0))
1275
0
            {
1276
0
                ret = XMLP_ret::XML_ERROR;
1277
0
            }
1278
0
        }
1279
0
        else if (config.compare(TLS_DEFAULT_VERIFY_PATH) == 0)
1280
0
        {
1281
0
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &pTCPDesc->tls_config.default_verify_path, 0))
1282
0
            {
1283
0
                ret = XMLP_ret::XML_ERROR;
1284
0
            }
1285
0
        }
1286
0
        else if (config.compare(TLS_RSA_PRIVATE_KEY_FILE) == 0)
1287
0
        {
1288
0
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &pTCPDesc->tls_config.rsa_private_key_file, 0))
1289
0
            {
1290
0
                ret = XMLP_ret::XML_ERROR;
1291
0
            }
1292
0
        }
1293
0
        else if (config.compare(TLS_HANDSHAKE_ROLE) == 0)
1294
0
        {
1295
0
            std::string handshake_mode;
1296
0
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &handshake_mode, 0))
1297
0
            {
1298
0
                ret = XMLP_ret::XML_ERROR;
1299
0
            }
1300
0
            else
1301
0
            {
1302
0
                if (handshake_mode.compare(TLS_HANDSHAKE_ROLE_DEFAULT) == 0)
1303
0
                {
1304
0
                    pTCPDesc->tls_config.handshake_role = TLSHandShakeMode::DEFAULT;
1305
0
                }
1306
0
                else if (handshake_mode.compare(TLS_HANDSHAKE_ROLE_SERVER) == 0)
1307
0
                {
1308
0
                    pTCPDesc->tls_config.handshake_role = TLSHandShakeMode::SERVER;
1309
0
                }
1310
0
                else if (handshake_mode.compare(TLS_HANDSHAKE_ROLE_CLIENT) == 0)
1311
0
                {
1312
0
                    pTCPDesc->tls_config.handshake_role = TLSHandShakeMode::CLIENT;
1313
0
                }
1314
0
                else
1315
0
                {
1316
0
                    EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing TLS configuration handshake_mode unrecognized "
1317
0
                            << handshake_mode << ".");
1318
0
                    ret = XMLP_ret::XML_ERROR;
1319
0
                }
1320
0
            }
1321
0
        }
1322
0
        else if (config.compare(TLS_SERVER_NAME) == 0)
1323
0
        {
1324
0
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &pTCPDesc->tls_config.server_name, 0))
1325
0
            {
1326
0
                ret = XMLP_ret::XML_ERROR;
1327
0
            }
1328
0
        }
1329
0
        else if (config.compare(TLS_VERIFY_MODE) == 0)
1330
0
        {
1331
0
            tinyxml2::XMLElement* p_verify = p_aux0->FirstChildElement();
1332
0
            while (p_verify != nullptr)
1333
0
            {
1334
0
                std::string type = p_verify->Value();
1335
0
                if (type.compare(TLS_VERIFY) == 0)
1336
0
                {
1337
0
                    std::string verify_mode;
1338
1339
0
                    if (XMLP_ret::XML_OK != getXMLString(p_verify, &verify_mode, 0))
1340
0
                    {
1341
0
                        ret = XMLP_ret::XML_ERROR;
1342
0
                    }
1343
0
                    else
1344
0
                    {
1345
0
                        if (verify_mode.compare(TLS_VERIFY_NONE) == 0)
1346
0
                        {
1347
0
                            pTCPDesc->tls_config.add_verify_mode(TLSVerifyMode::VERIFY_NONE);
1348
0
                        }
1349
0
                        else if (verify_mode.compare(TLS_VERIFY_PEER) == 0)
1350
0
                        {
1351
0
                            pTCPDesc->tls_config.add_verify_mode(TLSVerifyMode::VERIFY_PEER);
1352
0
                        }
1353
0
                        else if (verify_mode.compare(TLS_VERIFY_FAIL_IF_NO_PEER_CERT) == 0)
1354
0
                        {
1355
0
                            pTCPDesc->tls_config.add_verify_mode(TLSVerifyMode::VERIFY_FAIL_IF_NO_PEER_CERT);
1356
0
                        }
1357
0
                        else if (verify_mode.compare(TLS_VERIFY_CLIENT_ONCE) == 0)
1358
0
                        {
1359
0
                            pTCPDesc->tls_config.add_verify_mode(TLSVerifyMode::VERIFY_CLIENT_ONCE);
1360
0
                        }
1361
0
                        else
1362
0
                        {
1363
0
                            EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing TLS configuration verify_mode unrecognized "
1364
0
                                    << verify_mode << ".");
1365
0
                            ret = XMLP_ret::XML_ERROR;
1366
0
                        }
1367
0
                    }
1368
0
                }
1369
0
                else
1370
0
                {
1371
0
                    EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing TLS configuration found unrecognized node "
1372
0
                            << type << ".");
1373
0
                    ret = XMLP_ret::XML_ERROR;
1374
0
                }
1375
1376
0
                if (ret == XMLP_ret::XML_ERROR)
1377
0
                {
1378
                    // Break while loop
1379
0
                    break;
1380
0
                }
1381
1382
0
                p_verify = p_verify->NextSiblingElement();
1383
0
            }
1384
0
        }
1385
0
        else if (config.compare(TLS_OPTIONS) == 0)
1386
0
        {
1387
0
            tinyxml2::XMLElement* p_option = p_aux0->FirstChildElement();
1388
0
            while (p_option != nullptr)
1389
0
            {
1390
0
                std::string type = p_option->Value();
1391
0
                if (type.compare(TLS_OPTION) == 0)
1392
0
                {
1393
0
                    std::string option;
1394
1395
0
                    if (XMLP_ret::XML_OK != getXMLString(p_option, &option, 0))
1396
0
                    {
1397
0
                        ret = XMLP_ret::XML_ERROR;
1398
0
                    }
1399
0
                    else
1400
0
                    {
1401
0
                        if (option.compare(TLS_DEFAULT_WORKAROUNDS) == 0)
1402
0
                        {
1403
0
                            pTCPDesc->tls_config.add_option(TLSOption::DEFAULT_WORKAROUNDS);
1404
0
                        }
1405
0
                        else if (option.compare(TLS_NO_COMPRESSION) == 0)
1406
0
                        {
1407
0
                            pTCPDesc->tls_config.add_option(TLSOption::NO_COMPRESSION);
1408
0
                        }
1409
0
                        else if (option.compare(TLS_NO_SSLV2) == 0)
1410
0
                        {
1411
0
                            pTCPDesc->tls_config.add_option(TLSOption::NO_SSLV2);
1412
0
                        }
1413
0
                        else if (option.compare(TLS_NO_SSLV3) == 0)
1414
0
                        {
1415
0
                            pTCPDesc->tls_config.add_option(TLSOption::NO_SSLV3);
1416
0
                        }
1417
0
                        else if (option.compare(TLS_NO_TLSV1) == 0)
1418
0
                        {
1419
0
                            pTCPDesc->tls_config.add_option(TLSOption::NO_TLSV1);
1420
0
                        }
1421
0
                        else if (option.compare(TLS_NO_TLSV1_1) == 0)
1422
0
                        {
1423
0
                            pTCPDesc->tls_config.add_option(TLSOption::NO_TLSV1_1);
1424
0
                        }
1425
0
                        else if (option.compare(TLS_NO_TLSV1_2) == 0)
1426
0
                        {
1427
0
                            pTCPDesc->tls_config.add_option(TLSOption::NO_TLSV1_2);
1428
0
                        }
1429
0
                        else if (option.compare(TLS_NO_TLSV1_3) == 0)
1430
0
                        {
1431
0
                            pTCPDesc->tls_config.add_option(TLSOption::NO_TLSV1_3);
1432
0
                        }
1433
0
                        else if (option.compare(TLS_SINGLE_DH_USE) == 0)
1434
0
                        {
1435
0
                            pTCPDesc->tls_config.add_option(TLSOption::SINGLE_DH_USE);
1436
0
                        }
1437
0
                        else
1438
0
                        {
1439
0
                            EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing TLS configuration option unrecognized "
1440
0
                                    << option << ".");
1441
0
                            ret = XMLP_ret::XML_ERROR;
1442
0
                        }
1443
0
                    }
1444
0
                }
1445
0
                else
1446
0
                {
1447
0
                    EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing TLS options found unrecognized node "
1448
0
                            << type << ".");
1449
0
                    ret = XMLP_ret::XML_ERROR;
1450
0
                }
1451
1452
1453
0
                if (ret == XMLP_ret::XML_ERROR)
1454
0
                {
1455
                    // Break while loop
1456
0
                    break;
1457
0
                }
1458
1459
0
                p_option = p_option->NextSiblingElement();
1460
0
            }
1461
0
        }
1462
0
        else
1463
0
        {
1464
0
            EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing TLS configuration: Field " << config << " not recognized.");
1465
0
            ret = XMLP_ret::XML_ERROR;
1466
0
        }
1467
1468
        // Stop parsing on error
1469
0
        if (ret == XMLP_ret::XML_ERROR)
1470
0
        {
1471
0
            EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing TLS configuration's field '" << config << "'.");
1472
0
            break;
1473
0
        }
1474
0
    }
1475
1476
0
    return ret;
1477
0
}
1478
1479
XMLP_ret XMLParser::parseXMLReceptionThreads(
1480
        tinyxml2::XMLElement& p_root,
1481
        fastdds::rtps::PortBasedTransportDescriptor::ReceptionThreadsConfigMap& reception_threads)
1482
0
{
1483
    /*
1484
        <xs:complexType name="receptionThreadsListType">
1485
            <xs:sequence minOccurs="0" maxOccurs="unbounded">
1486
                <xs:element name="reception_thread" type="threadSettingsType" minOccurs="0" maxOccurs="unbounded"/>
1487
            </xs:sequence>
1488
        </xs:complexType>
1489
     */
1490
1491
    /*
1492
     * The only allowed element is <reception_thread>
1493
     */
1494
0
    XMLP_ret ret = XMLP_ret::XML_OK;
1495
0
    for (tinyxml2::XMLElement* p_element = p_root.FirstChildElement(); p_element != nullptr;
1496
0
            p_element = p_element->NextSiblingElement())
1497
0
    {
1498
0
        if (strcmp(p_element->Name(), RECEPTION_THREAD) == 0)
1499
0
        {
1500
0
            uint32_t port = 0;
1501
0
            fastdds::rtps::ThreadSettings thread_settings;
1502
0
            ret = getXMLThreadSettingsWithPort(*p_element, thread_settings, port);
1503
0
            if (XMLP_ret::XML_OK != ret || reception_threads.count(port) != 0)
1504
0
            {
1505
0
                EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing reception_threads thread settings. Port: " << port);
1506
0
                ret = XMLP_ret::XML_ERROR;
1507
0
                break;
1508
0
            }
1509
0
            reception_threads[port] = thread_settings;
1510
0
        }
1511
0
        else
1512
0
        {
1513
0
            EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing reception_threads. Wrong tag: " << p_element->Name());
1514
0
            ret = XMLP_ret::XML_ERROR;
1515
0
            break;
1516
0
        }
1517
0
    }
1518
0
    return ret;
1519
0
}
1520
1521
XMLP_ret XMLParser::parseXMLLibrarySettings(
1522
        tinyxml2::XMLElement* p_root)
1523
214
{
1524
    /*
1525
        <xs:complexType name="LibrarySettingsType">
1526
            <xs:all minOccurs="0">
1527
                <xs:element name="intraprocess_delivery" type="IntraprocessDeliveryType"/>
1528
            </xs:all>
1529
        </xs:complexType>
1530
     */
1531
1532
214
    XMLP_ret ret = XMLP_ret::XML_OK;
1533
214
    std::string sId = "";
1534
1535
214
    uint8_t ident = 1;
1536
214
    tinyxml2::XMLElement* p_aux0 = nullptr;
1537
214
    p_aux0 = p_root->FirstChildElement(INTRAPROCESS_DELIVERY);
1538
214
    if (nullptr == p_aux0)
1539
214
    {
1540
214
        EPROSIMA_LOG_ERROR(XMLPARSER, "Not found '" << INTRAPROCESS_DELIVERY << "' attribute");
1541
214
        return XMLP_ret::XML_ERROR;
1542
214
    }
1543
0
    else
1544
0
    {
1545
0
        fastdds::LibrarySettings library_settings;
1546
0
        if (XMLP_ret::XML_OK != getXMLEnum(p_aux0, &library_settings.intraprocess_delivery, ident))
1547
0
        {
1548
0
            return XMLP_ret::XML_ERROR;
1549
0
        }
1550
1551
0
        XMLProfileManager::library_settings(library_settings);
1552
0
    }
1553
1554
0
    return ret;
1555
214
}
1556
1557
XMLP_ret XMLParser::parseXMLDomainParticipantFactoryProf(
1558
        tinyxml2::XMLElement* p_root,
1559
        BaseNode& rootNode)
1560
13.3k
{
1561
13.3k
    XMLP_ret ret = XMLP_ret::XML_OK;
1562
13.3k
    up_participantfactory_t factory_qos{new fastdds::dds::DomainParticipantFactoryQos};
1563
13.3k
    up_node_participantfactory_t factory_node{new node_participantfactory_t{NodeType::DOMAINPARTICIPANT_FACTORY,
1564
13.3k
                                                                            std::move(factory_qos)}};
1565
13.3k
    if (XMLP_ret::XML_OK == fillDataNode(p_root, *factory_node))
1566
9.54k
    {
1567
9.54k
        rootNode.addChild(std::move(factory_node));
1568
9.54k
    }
1569
3.84k
    else
1570
3.84k
    {
1571
3.84k
        EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing participant profile");
1572
3.84k
        ret = XMLP_ret::XML_ERROR;
1573
3.84k
    }
1574
1575
13.3k
    return ret;
1576
13.3k
}
1577
1578
XMLP_ret XMLParser::parseXMLParticipantProf(
1579
        tinyxml2::XMLElement* p_root,
1580
        BaseNode& rootNode)
1581
83.2k
{
1582
83.2k
    XMLP_ret ret = XMLP_ret::XML_OK;
1583
83.2k
    up_participant_t participant_atts{new fastdds::xmlparser::ParticipantAttributes};
1584
83.2k
    up_node_participant_t participant_node{new node_participant_t{NodeType::PARTICIPANT, std::move(participant_atts)}};
1585
83.2k
    if (XMLP_ret::XML_OK == fillDataNode(p_root, *participant_node))
1586
34.5k
    {
1587
34.5k
        rootNode.addChild(std::move(participant_node));
1588
34.5k
    }
1589
48.6k
    else
1590
48.6k
    {
1591
48.6k
        EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing participant profile");
1592
48.6k
        ret = XMLP_ret::XML_ERROR;
1593
48.6k
    }
1594
1595
83.2k
    return ret;
1596
83.2k
}
1597
1598
XMLP_ret XMLParser::parseXMLPublisherProf(
1599
        tinyxml2::XMLElement* p_root,
1600
        BaseNode& rootNode)
1601
36.1k
{
1602
36.1k
    XMLP_ret ret = XMLP_ret::XML_OK;
1603
36.1k
    up_publisher_t publisher_atts{new fastdds::xmlparser::PublisherAttributes};
1604
36.1k
    up_node_publisher_t publisher_node{new node_publisher_t{NodeType::PUBLISHER, std::move(publisher_atts)}};
1605
36.1k
    if (XMLP_ret::XML_OK == fillDataNode(p_root, *publisher_node))
1606
21.2k
    {
1607
21.2k
        rootNode.addChild(std::move(publisher_node));
1608
21.2k
    }
1609
14.8k
    else
1610
14.8k
    {
1611
14.8k
        EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing publisher profile");
1612
14.8k
        ret = XMLP_ret::XML_ERROR;
1613
14.8k
    }
1614
36.1k
    return ret;
1615
36.1k
}
1616
1617
XMLP_ret XMLParser::parseXMLSubscriberProf(
1618
        tinyxml2::XMLElement* p_root,
1619
        BaseNode& rootNode)
1620
61.4k
{
1621
61.4k
    XMLP_ret ret = XMLP_ret::XML_OK;
1622
61.4k
    up_subscriber_t subscriber_atts{new fastdds::xmlparser::SubscriberAttributes};
1623
61.4k
    up_node_subscriber_t subscriber_node{new node_subscriber_t{NodeType::SUBSCRIBER, std::move(subscriber_atts)}};
1624
61.4k
    if (XMLP_ret::XML_OK == fillDataNode(p_root, *subscriber_node))
1625
46.4k
    {
1626
46.4k
        rootNode.addChild(std::move(subscriber_node));
1627
46.4k
    }
1628
15.0k
    else
1629
15.0k
    {
1630
15.0k
        EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing subscriber profile");
1631
15.0k
        ret = XMLP_ret::XML_ERROR;
1632
15.0k
    }
1633
61.4k
    return ret;
1634
61.4k
}
1635
1636
XMLP_ret XMLParser::parseXMLTopicData(
1637
        tinyxml2::XMLElement* p_root,
1638
        BaseNode& rootNode)
1639
23.7k
{
1640
23.7k
    XMLP_ret ret = XMLP_ret::XML_OK;
1641
23.7k
    up_topic_t topic_atts{new TopicAttributes};
1642
23.7k
    up_node_topic_t topic_node{new node_topic_t{NodeType::TOPIC, std::move(topic_atts)}};
1643
23.7k
    if (XMLP_ret::XML_OK == fillDataNode(p_root, *topic_node))
1644
20.1k
    {
1645
20.1k
        rootNode.addChild(std::move(topic_node));
1646
20.1k
    }
1647
3.62k
    else
1648
3.62k
    {
1649
3.62k
        EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing topic data node");
1650
3.62k
        ret = XMLP_ret::XML_ERROR;
1651
3.62k
    }
1652
23.7k
    return ret;
1653
23.7k
}
1654
1655
XMLP_ret XMLParser::parseXMLRequesterProf(
1656
        tinyxml2::XMLElement* p_root,
1657
        BaseNode& rootNode)
1658
12.0k
{
1659
12.0k
    XMLP_ret ret = XMLP_ret::XML_OK;
1660
12.0k
    up_requester_t requester_atts{new fastdds::xmlparser::RequesterAttributes};
1661
12.0k
    up_node_requester_t requester_node{new node_requester_t{NodeType::REQUESTER, std::move(requester_atts)}};
1662
12.0k
    if (XMLP_ret::XML_OK == fillDataNode(p_root, *requester_node))
1663
6.82k
    {
1664
6.82k
        rootNode.addChild(std::move(requester_node));
1665
6.82k
    }
1666
5.22k
    else
1667
5.22k
    {
1668
5.22k
        EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing requester profile");
1669
5.22k
        ret = XMLP_ret::XML_ERROR;
1670
5.22k
    }
1671
12.0k
    return ret;
1672
12.0k
}
1673
1674
XMLP_ret XMLParser::parseXMLReplierProf(
1675
        tinyxml2::XMLElement* p_root,
1676
        BaseNode& rootNode)
1677
12.6k
{
1678
12.6k
    XMLP_ret ret = XMLP_ret::XML_OK;
1679
12.6k
    up_replier_t replier_atts{new fastdds::xmlparser::ReplierAttributes};
1680
12.6k
    up_node_replier_t replier_node{new node_replier_t{NodeType::REPLIER, std::move(replier_atts)}};
1681
12.6k
    if (XMLP_ret::XML_OK == fillDataNode(p_root, *replier_node))
1682
5.43k
    {
1683
5.43k
        rootNode.addChild(std::move(replier_node));
1684
5.43k
    }
1685
7.17k
    else
1686
7.17k
    {
1687
7.17k
        EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing replier profile");
1688
7.17k
        ret = XMLP_ret::XML_ERROR;
1689
7.17k
    }
1690
12.6k
    return ret;
1691
12.6k
}
1692
1693
XMLP_ret XMLParser::parseProfiles(
1694
        tinyxml2::XMLElement* p_root,
1695
        BaseNode& profilesNode)
1696
16.1k
{
1697
    /*
1698
        <xs:element name="profiles">
1699
            <xs:complexType>
1700
                <xs:sequence>
1701
                    <xs:element name="library_settings" type="LibrarySettingsType" minOccurs="0" maxOccurs="unbounded"/>
1702
                    <xs:element name="transport_descriptors" type="TransportDescriptorListType" minOccurs="0" maxOccurs="unbounded"/>
1703
                    <xs:element name="participant" type="participantProfileType" minOccurs="0" maxOccurs="unbounded"/>
1704
                    <xs:element name="publisher" type="publisherProfileType" minOccurs="0" maxOccurs="unbounded"/>
1705
                    <xs:element name="subscriber" type="subscriberProfileType" minOccurs="0" maxOccurs="unbounded"/>
1706
                    <xs:element name="topic" type="topicAttributesType" minOccurs="0" maxOccurs="unbounded"/>
1707
                </xs:sequence>
1708
            </xs:complexType>
1709
        </xs:element>
1710
     */
1711
1712
16.1k
    tinyxml2::XMLElement* p_profile = p_root->FirstChildElement();
1713
16.1k
    const char* tag = nullptr;
1714
16.1k
    bool parseOk = true;
1715
16.1k
    XMLP_ret ret = XMLP_ret::XML_OK;
1716
424k
    while (nullptr != p_profile)
1717
408k
    {
1718
408k
        if (nullptr != (tag = p_profile->Value()))
1719
408k
        {
1720
            // If profile parsing functions fails, log and continue.
1721
408k
            if (strcmp(tag, TRANSPORT_DESCRIPTORS) == 0)
1722
241
            {
1723
241
                parseOk &= parseXMLTransportsProf(p_profile) == XMLP_ret::XML_OK;
1724
241
            }
1725
408k
            else if (strcmp(tag, LIBRARY_SETTINGS) == 0)
1726
212
            {
1727
212
                parseOk &= parseXMLLibrarySettings(p_profile) == XMLP_ret::XML_OK;
1728
212
            }
1729
407k
            else if (strcmp(tag, DOMAINPARTICIPANT_FACTORY) == 0)
1730
13.1k
            {
1731
13.1k
                parseOk &= parseXMLDomainParticipantFactoryProf(p_profile, profilesNode) == XMLP_ret::XML_OK;
1732
13.1k
            }
1733
394k
            else if (strcmp(tag, PARTICIPANT) == 0)
1734
82.5k
            {
1735
82.5k
                parseOk &= parseXMLParticipantProf(p_profile, profilesNode) == XMLP_ret::XML_OK;
1736
82.5k
            }
1737
312k
            else if (strcmp(tag, PUBLISHER) == 0 || strcmp(tag, DATA_WRITER) == 0)
1738
32.0k
            {
1739
32.0k
                parseOk &= parseXMLPublisherProf(p_profile, profilesNode) == XMLP_ret::XML_OK;
1740
32.0k
            }
1741
280k
            else if (strcmp(tag, SUBSCRIBER) == 0 || strcmp(tag, DATA_READER) == 0)
1742
57.0k
            {
1743
57.0k
                parseOk &= parseXMLSubscriberProf(p_profile, profilesNode) == XMLP_ret::XML_OK;
1744
57.0k
            }
1745
223k
            else if (strcmp(tag, TOPIC) == 0)
1746
22.1k
            {
1747
22.1k
                parseOk &= parseXMLTopicData(p_profile, profilesNode) == XMLP_ret::XML_OK;
1748
22.1k
            }
1749
200k
            else if (strcmp(tag, TYPES) == 0)
1750
158k
            {
1751
158k
                parseOk &= parseXMLTypes(p_profile) == XMLP_ret::XML_OK;
1752
158k
            }
1753
42.3k
            else if (strcmp(tag, REQUESTER) == 0)
1754
11.2k
            {
1755
11.2k
                parseOk &= parseXMLRequesterProf(p_profile, profilesNode) == XMLP_ret::XML_OK;
1756
11.2k
            }
1757
31.0k
            else if (strcmp(tag, REPLIER) == 0)
1758
12.1k
            {
1759
12.1k
                parseOk &= parseXMLReplierProf(p_profile, profilesNode) == XMLP_ret::XML_OK;
1760
12.1k
            }
1761
18.8k
            else if (strcmp(tag, QOS_PROFILE) == 0)
1762
714
            {
1763
714
                EPROSIMA_LOG_ERROR(XMLPARSER, "Field 'QOS_PROFILE' do not supported for now");
1764
714
            }
1765
18.1k
            else if (strcmp(tag, APPLICATION) == 0)
1766
281
            {
1767
281
                EPROSIMA_LOG_ERROR(XMLPARSER, "Field 'APPLICATION' do not supported for now");
1768
281
            }
1769
17.8k
            else if (strcmp(tag, TYPE) == 0)
1770
1.27k
            {
1771
1.27k
                EPROSIMA_LOG_ERROR(XMLPARSER, "Field 'TYPE' do not supported for now");
1772
1.27k
            }
1773
16.6k
            else
1774
16.6k
            {
1775
16.6k
                parseOk = false;
1776
16.6k
                EPROSIMA_LOG_ERROR(XMLPARSER, "Not expected tag: '" << tag << "'");
1777
16.6k
            }
1778
408k
        }
1779
1780
408k
        if (!parseOk)
1781
331k
        {
1782
331k
            EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing profile's tag " << tag);
1783
331k
            ret = XMLP_ret::XML_ERROR;
1784
331k
        }
1785
408k
        p_profile = p_profile->NextSiblingElement();
1786
408k
    }
1787
16.1k
    return ret;
1788
16.1k
}
1789
1790
XMLP_ret XMLParser::parseLogConfig(
1791
        tinyxml2::XMLElement* p_root)
1792
3.64k
{
1793
    /*
1794
        <xs:element name="log" type="logType"/>
1795
        <xs:complexType name="logType">
1796
            <xs:sequence minOccurs="1" maxOccurs="unbounded">
1797
                <xs:choice minOccurs="1">
1798
                    <xs:element name="use_default" type="booleanCaps" minOccurs="0" maxOccurs="1"/>
1799
                    <xs:element name="consumer" type="logConsumerType" minOccurs="0" maxOccurs="unbounded"/>
1800
                    <xs:element name="thread_settings" type="threadSettingsType" minOccurs="0" maxOccurs="1"/>
1801
                </xs:choice>
1802
            </xs:sequence>
1803
        </xs:complexType>
1804
     */
1805
1806
    /*
1807
     * TODO(eduponz): Uphold XSD validation in parsing
1808
     *   Even though the XSD above enforces the log tag to have at least one consumer,
1809
     *   the parsing allows for an empty log tag (e.g. `<log></log>`).
1810
     *   This inconsistency is kept to keep a backwards compatible behaviour.
1811
     *   In fact, test XMLParserTests.parseXMLNoRoot even checks that an empty log tag
1812
     *   is valid.
1813
     */
1814
1815
3.64k
    XMLP_ret ret = XMLP_ret::XML_OK;
1816
1817
3.64k
    tinyxml2::XMLElement* p_aux0 = p_root->FirstChildElement(LOG);
1818
3.64k
    if (p_aux0 == nullptr)
1819
3.62k
    {
1820
3.62k
        p_aux0 = p_root;
1821
3.62k
    }
1822
1823
3.64k
    std::set<std::string> tags_present;
1824
3.64k
    tinyxml2::XMLElement* p_element = p_aux0->FirstChildElement();
1825
3.64k
    fastdds::rtps::ThreadSettings thread_settings;
1826
3.64k
    bool set_thread_settings = false;
1827
1828
5.12k
    while (ret == XMLP_ret::XML_OK && nullptr != p_element)
1829
1.48k
    {
1830
1.48k
        const char* name = p_element->Name();
1831
1.48k
        const char* tag = p_element->Value();
1832
1833
        // Fail on duplicated not allowed elements
1834
1.48k
        if (strcmp(tag, CONSUMER) != 0 && tags_present.count(name) != 0)
1835
1
        {
1836
1
            EPROSIMA_LOG_ERROR(XMLPARSER, "Duplicated element found in 'log'. Tag: " << name);
1837
1
            return XMLP_ret::XML_ERROR;
1838
1
        }
1839
1.48k
        tags_present.emplace(name);
1840
1841
1.48k
        if (nullptr != tag)
1842
1.48k
        {
1843
1.48k
            if (strcmp(tag, USE_DEFAULT) == 0)
1844
3
            {
1845
3
                std::string auxBool = get_element_text(p_element);
1846
3
                if (auxBool.empty())
1847
3
                {
1848
3
                    EPROSIMA_LOG_ERROR(XMLPARSER, "Cannot get text from tag: '" << tag << "'");
1849
3
                    ret = XMLP_ret::XML_ERROR;
1850
3
                }
1851
1852
3
                if (ret == XMLP_ret::XML_OK)
1853
0
                {
1854
0
                    bool use_default = true;
1855
0
                    if (std::strcmp(auxBool.c_str(), "FALSE") == 0)
1856
0
                    {
1857
0
                        use_default = false;
1858
0
                    }
1859
0
                    if (!use_default)
1860
0
                    {
1861
0
                        eprosima::fastdds::dds::Log::ClearConsumers();
1862
0
                    }
1863
0
                }
1864
3
            }
1865
1.48k
            else if (strcmp(tag, CONSUMER) == 0)
1866
289
            {
1867
289
                ret = parseXMLConsumer(*p_element);
1868
289
            }
1869
1.19k
            else if (strcmp(tag, THREAD_SETTINGS) == 0)
1870
845
            {
1871
845
                ret = getXMLThreadSettings(*p_element, thread_settings);
1872
845
                if (ret == XMLP_ret::XML_OK)
1873
540
                {
1874
540
                    set_thread_settings = true;
1875
540
                }
1876
305
                else
1877
305
                {
1878
305
                    EPROSIMA_LOG_ERROR(XMLPARSER, "Incorrect thread settings");
1879
305
                }
1880
845
            }
1881
348
            else
1882
348
            {
1883
348
                EPROSIMA_LOG_ERROR(XMLPARSER, "Not expected tag: '" << tag << "'");
1884
348
                ret = XMLP_ret::XML_ERROR;
1885
348
            }
1886
1.48k
        }
1887
1888
1.48k
        if (ret == XMLP_ret::XML_OK)
1889
829
        {
1890
829
            p_element = p_element->NextSiblingElement();
1891
829
        }
1892
1.48k
    }
1893
1894
3.64k
    if (ret == XMLP_ret::XML_OK && set_thread_settings)
1895
520
    {
1896
520
        fastdds::dds::Log::SetThreadConfig(thread_settings);
1897
520
    }
1898
1899
3.64k
    return ret;
1900
3.64k
}
1901
1902
XMLP_ret XMLParser::parseXMLConsumer(
1903
        tinyxml2::XMLElement& consumer)
1904
289
{
1905
289
    using namespace eprosima::fastdds::dds;
1906
1907
289
    XMLP_ret ret = XMLP_ret::XML_OK;
1908
289
    tinyxml2::XMLElement* p_element = consumer.FirstChildElement(CLASS);
1909
1910
289
    if (p_element != nullptr)
1911
0
    {
1912
0
        std::string classStr = get_element_text(p_element);
1913
1914
0
        if (std::strcmp(classStr.c_str(), "StdoutConsumer") == 0)
1915
0
        {
1916
0
            Log::RegisterConsumer(std::unique_ptr<LogConsumer>(new StdoutConsumer));
1917
0
        }
1918
0
        else if (std::strcmp(classStr.c_str(), "StdoutErrConsumer") == 0)
1919
0
        {
1920
            /* Register a StdoutErrConsumer */
1921
1922
            // Get first property
1923
0
            tinyxml2::XMLElement* property = consumer.FirstChildElement(PROPERTY);
1924
0
            if (nullptr == property)
1925
0
            {
1926
                // If no properties are specified, create the consumer with default values
1927
0
                Log::RegisterConsumer(std::unique_ptr<LogConsumer>(new StdoutErrConsumer));
1928
0
            }
1929
0
            else
1930
0
            {
1931
                // Only one property is supported. Its name is `stderr_threshold`, and its value is a log kind specified
1932
                // as a string in the form `Log::Kind::<Kind>`.
1933
0
                tinyxml2::XMLElement* p_auxName = nullptr;    // Property name
1934
0
                tinyxml2::XMLElement* p_auxValue = nullptr;   // Property value
1935
0
                uint8_t stderr_threshold_property_count = 0;  // Occurrences count. Only one is allowed
1936
1937
                // Get default threshold
1938
0
                Log::Kind threshold = StdoutErrConsumer::STDERR_THRESHOLD_DEFAULT;
1939
1940
                // Iterate over the properties
1941
0
                while (nullptr != property)
1942
0
                {
1943
0
                    if (nullptr != (p_auxName = property->FirstChildElement(NAME)))
1944
0
                    {
1945
                        // Get property name
1946
0
                        std::string s = get_element_text(p_auxName);
1947
1948
0
                        if (std::strcmp(s.c_str(), "stderr_threshold") == 0)
1949
0
                        {
1950
                            /* Property is a `stderr_threshold` */
1951
1952
                            // Update occurrence count and check how many encountered. Only the first one applies, the
1953
                            // rest are ignored.
1954
0
                            stderr_threshold_property_count++;
1955
0
                            if (stderr_threshold_property_count > 1)
1956
0
                            {
1957
                                // Continue with the next property if `stderr_threshold` had been already specified.
1958
0
                                EPROSIMA_LOG_ERROR(XMLParser,
1959
0
                                        classStr << " only supports one occurrence of 'stderr_threshold'."
1960
0
                                                 << " Only the first one is applied.");
1961
0
                                property = property->NextSiblingElement(PROPERTY);
1962
0
                                ret = XMLP_ret::XML_NOK;
1963
0
                                continue;
1964
0
                            }
1965
1966
                            // Get the property value. It should be a Log::Kind.
1967
0
                            if (nullptr != (p_auxValue = property->FirstChildElement(VALUE)))
1968
0
                            {
1969
                                // Get property value and use it to set the threshold.
1970
0
                                std::string threshold_str = get_element_text(p_auxValue);
1971
0
                                if (std::strcmp(threshold_str.c_str(), "Log::Kind::Error") == 0)
1972
0
                                {
1973
0
                                    threshold = Log::Kind::Error;
1974
0
                                }
1975
0
                                else if (std::strcmp(threshold_str.c_str(), "Log::Kind::Warning") == 0)
1976
0
                                {
1977
0
                                    threshold = Log::Kind::Warning;
1978
0
                                }
1979
0
                                else if (std::strcmp(threshold_str.c_str(), "Log::Kind::Info") == 0)
1980
0
                                {
1981
0
                                    threshold = Log::Kind::Info;
1982
0
                                }
1983
0
                                else
1984
0
                                {
1985
0
                                    EPROSIMA_LOG_ERROR(XMLParser, "Unkown Log::Kind '" << threshold_str
1986
0
                                                                                       << "'. Using default threshold.");
1987
0
                                    ret = XMLP_ret::XML_NOK;
1988
0
                                }
1989
0
                            }
1990
0
                        }
1991
0
                        else
1992
0
                        {
1993
0
                            EPROSIMA_LOG_ERROR(XMLParser, "Unkown property value '" << s << "' in " << classStr
1994
0
                                                                                    << " log consumer");
1995
0
                            ret = XMLP_ret::XML_NOK;
1996
0
                        }
1997
0
                    }
1998
                    // Continue with the next property
1999
0
                    property = property->NextSiblingElement(PROPERTY);
2000
0
                }
2001
2002
                // Create consumer with the specified `stderr_threshold` and register it.
2003
0
                StdoutErrConsumer* log_consumer = new StdoutErrConsumer;
2004
0
                log_consumer->stderr_threshold(threshold);
2005
0
                Log::RegisterConsumer(std::unique_ptr<LogConsumer>(log_consumer));
2006
0
            }
2007
0
        }
2008
0
        else if (std::strcmp(classStr.c_str(), "FileConsumer") == 0)
2009
0
        {
2010
0
            std::string outputFile = "output.log";
2011
0
            bool append = false;
2012
2013
0
            tinyxml2::XMLElement* property = consumer.FirstChildElement(PROPERTY);
2014
0
            if (nullptr == property)
2015
0
            {
2016
0
                Log::RegisterConsumer(std::unique_ptr<LogConsumer>(new FileConsumer));
2017
0
            }
2018
0
            else
2019
0
            {
2020
0
                tinyxml2::XMLElement* p_auxName = nullptr;
2021
0
                tinyxml2::XMLElement* p_auxValue = nullptr;
2022
0
                while (nullptr != property)
2023
0
                {
2024
                    // name - stringType
2025
0
                    if (nullptr != (p_auxName = property->FirstChildElement(NAME)))
2026
0
                    {
2027
0
                        std::string s = get_element_text(p_auxName);
2028
2029
0
                        if (std::strcmp(s.c_str(), "filename") == 0)
2030
0
                        {
2031
0
                            if (nullptr == (p_auxValue = property->FirstChildElement(VALUE)) ||
2032
0
                                    !get_element_text(p_auxValue, outputFile))
2033
0
                            {
2034
0
                                EPROSIMA_LOG_ERROR(XMLParser, "Filename value cannot be found for " << classStr
2035
0
                                                                                                    << " log consumer.");
2036
0
                                ret = XMLP_ret::XML_NOK;
2037
0
                            }
2038
0
                        }
2039
0
                        else if (std::strcmp(s.c_str(), "append") == 0)
2040
0
                        {
2041
0
                            std::string auxBool;
2042
0
                            if (nullptr != (p_auxValue = property->FirstChildElement(VALUE)) &&
2043
0
                                    get_element_text(p_auxValue, auxBool))
2044
0
                            {
2045
0
                                if (std::strcmp(auxBool.c_str(), "TRUE") == 0)
2046
0
                                {
2047
0
                                    append = true;
2048
0
                                }
2049
0
                            }
2050
0
                            else
2051
0
                            {
2052
0
                                EPROSIMA_LOG_ERROR(XMLParser, "Append value cannot be found for " << classStr
2053
0
                                                                                                  << " log consumer.");
2054
0
                                ret = XMLP_ret::XML_NOK;
2055
0
                            }
2056
0
                        }
2057
0
                        else
2058
0
                        {
2059
0
                            EPROSIMA_LOG_ERROR(XMLParser, "Unknown property " << s << " in " << classStr
2060
0
                                                                              << " log consumer.");
2061
0
                            ret = XMLP_ret::XML_NOK;
2062
0
                        }
2063
0
                    }
2064
0
                    property = property->NextSiblingElement(PROPERTY);
2065
0
                }
2066
2067
0
                Log::RegisterConsumer(std::unique_ptr<LogConsumer>(new FileConsumer(outputFile, append)));
2068
0
            }
2069
0
        }
2070
0
        else
2071
0
        {
2072
0
            EPROSIMA_LOG_ERROR(XMLParser, "Unknown log consumer class: " << classStr);
2073
0
            ret = XMLP_ret::XML_ERROR;
2074
0
        }
2075
0
    }
2076
2077
289
    return ret;
2078
289
}
2079
2080
XMLP_ret XMLParser::loadXML(
2081
        const std::string& filename,
2082
        up_base_node_t& root)
2083
0
{
2084
0
    return loadXML(filename, root, false);
2085
0
}
2086
2087
XMLP_ret XMLParser::loadXML(
2088
        const std::string& filename,
2089
        up_base_node_t& root,
2090
        bool is_default)
2091
0
{
2092
0
    if (filename.empty())
2093
0
    {
2094
0
        EPROSIMA_LOG_ERROR(XMLPARSER, "Error loading XML file, filename empty");
2095
0
        return XMLP_ret::XML_ERROR;
2096
0
    }
2097
2098
0
    tinyxml2::XMLDocument xmlDoc;
2099
0
    if (tinyxml2::XMLError::XML_SUCCESS != xmlDoc.LoadFile(filename.c_str()))
2100
0
    {
2101
0
        if (!is_default)
2102
0
        {
2103
0
            EPROSIMA_LOG_ERROR(XMLPARSER, "Error opening '" << filename << "'");
2104
0
        }
2105
0
        return XMLP_ret::XML_ERROR;
2106
0
    }
2107
2108
0
    EPROSIMA_LOG_INFO(XMLPARSER, "File '" << filename << "' opened successfully");
2109
0
    return parseXML(xmlDoc, root);
2110
0
}
2111
2112
XMLP_ret XMLParser::loadXMLProfiles(
2113
        tinyxml2::XMLElement& xmlDoc,
2114
        up_base_node_t& root)
2115
0
{
2116
0
    return parseXMLProfiles(xmlDoc, root);
2117
0
}
2118
2119
XMLP_ret XMLParser::loadXML(
2120
        tinyxml2::XMLDocument& xmlDoc,
2121
        up_base_node_t& root)
2122
0
{
2123
0
    return parseXML(xmlDoc, root);
2124
0
}
2125
2126
XMLP_ret XMLParser::loadXML(
2127
        const char* data,
2128
        size_t length,
2129
        up_base_node_t& root)
2130
22.2k
{
2131
22.2k
    tinyxml2::XMLDocument xmlDoc;
2132
22.2k
    if (tinyxml2::XMLError::XML_SUCCESS != xmlDoc.Parse(data, length))
2133
123
    {
2134
123
        EPROSIMA_LOG_ERROR(XMLPARSER, "Error parsing XML buffer");
2135
123
        return XMLP_ret::XML_ERROR;
2136
123
    }
2137
22.1k
    return parseXML(xmlDoc, root);
2138
22.2k
}
2139
2140
template<typename T>
2141
void XMLParser::addAllAttributes(
2142
        tinyxml2::XMLElement* p_profile,
2143
        DataNode<T>& node)
2144
242k
{
2145
242k
    const tinyxml2::XMLAttribute* attrib;
2146
436k
    for (attrib = p_profile->FirstAttribute(); attrib != nullptr; attrib = attrib->Next())
2147
193k
    {
2148
193k
        node.addAttribute(attrib->Name(), attrib->Value());
2149
193k
    }
2150
242k
}
void eprosima::fastdds::xmlparser::XMLParser::addAllAttributes<eprosima::fastdds::xmlparser::TopicAttributes>(tinyxml2::XMLElement*, eprosima::fastdds::xmlparser::DataNode<eprosima::fastdds::xmlparser::TopicAttributes>&)
Line
Count
Source
2144
23.7k
{
2145
23.7k
    const tinyxml2::XMLAttribute* attrib;
2146
45.5k
    for (attrib = p_profile->FirstAttribute(); attrib != nullptr; attrib = attrib->Next())
2147
21.8k
    {
2148
21.8k
        node.addAttribute(attrib->Name(), attrib->Value());
2149
21.8k
    }
2150
23.7k
}
void eprosima::fastdds::xmlparser::XMLParser::addAllAttributes<eprosima::fastdds::dds::DomainParticipantFactoryQos>(tinyxml2::XMLElement*, eprosima::fastdds::xmlparser::DataNode<eprosima::fastdds::dds::DomainParticipantFactoryQos>&)
Line
Count
Source
2144
13.3k
{
2145
13.3k
    const tinyxml2::XMLAttribute* attrib;
2146
27.9k
    for (attrib = p_profile->FirstAttribute(); attrib != nullptr; attrib = attrib->Next())
2147
14.5k
    {
2148
14.5k
        node.addAttribute(attrib->Name(), attrib->Value());
2149
14.5k
    }
2150
13.3k
}
void eprosima::fastdds::xmlparser::XMLParser::addAllAttributes<eprosima::fastdds::xmlparser::ParticipantAttributes>(tinyxml2::XMLElement*, eprosima::fastdds::xmlparser::DataNode<eprosima::fastdds::xmlparser::ParticipantAttributes>&)
Line
Count
Source
2144
83.2k
{
2145
83.2k
    const tinyxml2::XMLAttribute* attrib;
2146
102k
    for (attrib = p_profile->FirstAttribute(); attrib != nullptr; attrib = attrib->Next())
2147
19.4k
    {
2148
19.4k
        node.addAttribute(attrib->Name(), attrib->Value());
2149
19.4k
    }
2150
83.2k
}
void eprosima::fastdds::xmlparser::XMLParser::addAllAttributes<eprosima::fastdds::xmlparser::PublisherAttributes>(tinyxml2::XMLElement*, eprosima::fastdds::xmlparser::DataNode<eprosima::fastdds::xmlparser::PublisherAttributes>&)
Line
Count
Source
2144
36.1k
{
2145
36.1k
    const tinyxml2::XMLAttribute* attrib;
2146
58.2k
    for (attrib = p_profile->FirstAttribute(); attrib != nullptr; attrib = attrib->Next())
2147
22.1k
    {
2148
22.1k
        node.addAttribute(attrib->Name(), attrib->Value());
2149
22.1k
    }
2150
36.1k
}
void eprosima::fastdds::xmlparser::XMLParser::addAllAttributes<eprosima::fastdds::xmlparser::SubscriberAttributes>(tinyxml2::XMLElement*, eprosima::fastdds::xmlparser::DataNode<eprosima::fastdds::xmlparser::SubscriberAttributes>&)
Line
Count
Source
2144
61.4k
{
2145
61.4k
    const tinyxml2::XMLAttribute* attrib;
2146
85.0k
    for (attrib = p_profile->FirstAttribute(); attrib != nullptr; attrib = attrib->Next())
2147
23.6k
    {
2148
23.6k
        node.addAttribute(attrib->Name(), attrib->Value());
2149
23.6k
    }
2150
61.4k
}
void eprosima::fastdds::xmlparser::XMLParser::addAllAttributes<eprosima::fastdds::xmlparser::RequesterAttributes>(tinyxml2::XMLElement*, eprosima::fastdds::xmlparser::DataNode<eprosima::fastdds::xmlparser::RequesterAttributes>&)
Line
Count
Source
2144
12.0k
{
2145
12.0k
    const tinyxml2::XMLAttribute* attrib;
2146
53.6k
    for (attrib = p_profile->FirstAttribute(); attrib != nullptr; attrib = attrib->Next())
2147
41.5k
    {
2148
41.5k
        node.addAttribute(attrib->Name(), attrib->Value());
2149
41.5k
    }
2150
12.0k
}
void eprosima::fastdds::xmlparser::XMLParser::addAllAttributes<eprosima::fastdds::xmlparser::ReplierAttributes>(tinyxml2::XMLElement*, eprosima::fastdds::xmlparser::DataNode<eprosima::fastdds::xmlparser::ReplierAttributes>&)
Line
Count
Source
2144
12.6k
{
2145
12.6k
    const tinyxml2::XMLAttribute* attrib;
2146
63.1k
    for (attrib = p_profile->FirstAttribute(); attrib != nullptr; attrib = attrib->Next())
2147
50.5k
    {
2148
50.5k
        node.addAttribute(attrib->Name(), attrib->Value());
2149
50.5k
    }
2150
12.6k
}
2151
2152
XMLP_ret XMLParser::fillDataNode(
2153
        tinyxml2::XMLElement* node,
2154
        DataNode<TopicAttributes>& topic_node)
2155
23.7k
{
2156
23.7k
    if (nullptr == node)
2157
0
    {
2158
0
        EPROSIMA_LOG_ERROR(XMLPARSER, "Bad parameters!");
2159
0
        return XMLP_ret::XML_ERROR;
2160
0
    }
2161
2162
23.7k
    addAllAttributes(node, topic_node);
2163
2164
23.7k
    uint8_t ident = 1;
2165
23.7k
    if (XMLP_ret::XML_OK != getXMLTopicAttributes(node, *topic_node.get(), ident))
2166
3.62k
    {
2167
3.62k
        return XMLP_ret::XML_ERROR;
2168
3.62k
    }
2169
2170
20.1k
    return XMLP_ret::XML_OK;
2171
23.7k
}
2172
2173
XMLP_ret XMLParser::fillDataNode(
2174
        tinyxml2::XMLElement* p_profile,
2175
        DataNode<fastdds::dds::DomainParticipantFactoryQos>& factory_node)
2176
13.3k
{
2177
    /*
2178
       <xs:complexType name="domainParticipantFactoryProfileType">
2179
        <xs:all>
2180
            <xs:element name="qos" type="domainParticipantFactoryQosPoliciesType" minOccurs="0" maxOccurs="1"/>
2181
        </xs:all>
2182
        <xs:attribute name="profile_name" type="string" use="required"/>
2183
        <xs:attribute name="is_default_profile" type="boolean" use="optional"/>
2184
       </xs:complexType>
2185
     */
2186
2187
13.3k
    if (nullptr == p_profile)
2188
0
    {
2189
0
        EPROSIMA_LOG_ERROR(XMLPARSER, "Bad parameters!");
2190
0
        return XMLP_ret::XML_ERROR;
2191
0
    }
2192
2193
13.3k
    addAllAttributes(p_profile, factory_node);
2194
2195
    /*
2196
     * The only allowed element <qos>, and its max is 1; look for it.
2197
     */
2198
13.3k
    std::set<std::string> tags_present;
2199
26.9k
    for (tinyxml2::XMLElement* p_element = p_profile->FirstChildElement(); p_element != nullptr;
2200
13.5k
            p_element = p_element->NextSiblingElement())
2201
17.4k
    {
2202
17.4k
        const char* name = p_element->Name();
2203
17.4k
        if (tags_present.count(name) != 0)
2204
603
        {
2205
603
            EPROSIMA_LOG_ERROR(XMLPARSER, "Duplicated element found in 'participant'. Tag: " << name);
2206
603
            return XMLP_ret::XML_ERROR;
2207
603
        }
2208
16.8k
        tags_present.emplace(name);
2209
2210
16.8k
        if (strcmp(p_element->Name(), QOS) == 0)
2211
3.41k
        {
2212
3.41k
            if (XMLP_ret::XML_OK != getXMLDomainParticipantFactoryQos(*p_element, *factory_node.get()))
2213
3.24k
            {
2214
3.24k
                return XMLP_ret::XML_ERROR;
2215
3.24k
            }
2216
3.41k
        }
2217
16.8k
    }
2218
9.54k
    return XMLP_ret::XML_OK;
2219
13.3k
}
2220
2221
XMLP_ret XMLParser::fillDataNode(
2222
        tinyxml2::XMLElement* p_profile,
2223
        DataNode<fastdds::xmlparser::ParticipantAttributes>& participant_node)
2224
83.2k
{
2225
    /*
2226
        <xs:complexType name="participantProfileType">
2227
            <xs:all>
2228
                <xs:element name="domainId" type="domainIDType" minOccurs="0" maxOccurs="1"/>
2229
                <xs:element name="rtps" minOccurs="0" maxOccurs="1">
2230
                    <xs:complexType>
2231
                        <xs:all>
2232
                            <xs:element name="name" type="string" minOccurs="0" maxOccurs="1"/>
2233
                            <xs:element name="defaultUnicastLocatorList" type="locatorListType" minOccurs="0" maxOccurs="1"/>
2234
                            <xs:element name="defaultMulticastLocatorList" type="locatorListType" minOccurs="0" maxOccurs="1"/>
2235
                            <xs:element name="default_external_unicast_locators" type="externalLocatorListType" minOccurs="0" maxOccurs="1"/>
2236
                            <xs:element name="ignore_non_matching_locators" type="boolean" minOccurs="0" maxOccurs="1"/>
2237
                            <xs:element name="sendSocketBufferSize" type="uint32" minOccurs="0" maxOccurs="1"/>
2238
                            <xs:element name="listenSocketBufferSize" type="uint32" minOccurs="0" maxOccurs="1"/>
2239
                            <xs:element name="netmask_filter" minOccurs="0" maxOccurs="1">
2240
                                <xs:simpleType>
2241
                                    <xs:restriction base="xs:string">
2242
                                        <xs:enumeration value="OFF"/>
2243
                                        <xs:enumeration value="AUTO"/>
2244
                                        <xs:enumeration value="ON"/>
2245
                                    </xs:restriction>
2246
                                </xs:simpleType>
2247
                            </xs:element>
2248
                            <xs:element name="builtin" type="builtinAttributesType" minOccurs="0" maxOccurs="1"/>
2249
                            <xs:element name="port" type="portType" minOccurs="0" maxOccurs="1"/>
2250
                            <xs:element name="participantID" type="int32" minOccurs="0" maxOccurs="1"/>
2251
                            <xs:element name="easy_mode_ip" type="string" minOccurs="0" maxOccurs="1"/>
2252
                            <xs:element name="userTransports" minOccurs="0" maxOccurs="1">
2253
                                <xs:complexType>
2254
                                    <xs:sequence>
2255
                                        <xs:element name="transport_id" type="string" minOccurs="1" maxOccurs="unbounded"/>
2256
                                    </xs:sequence>
2257
                                </xs:complexType>
2258
                            </xs:element>
2259
                            <xs:element name="useBuiltinTransports" type="boolean" minOccurs="0" maxOccurs="1"/>
2260
                            <xs:element name="builtinTransports" type="builtinTransportsType" minOccurs="0" maxOccurs="1"/>
2261
                            <xs:element name="propertiesPolicy" type="propertyPolicyType" minOccurs="0" maxOccurs="1"/>
2262
                            <xs:element name="allocation" type="rtpsParticipantAllocationAttributesType"  minOccurs="0" maxOccurs="1"/>
2263
                            <xs:element name="userData" type="octectVectorQosPolicyType" minOccurs="0" maxOccurs="1"/>
2264
                            <xs:element name="prefix" type="prefixType" minOccurs="0" maxOccurs="1"/>
2265
                            <xs:element name="flow_controller_descriptor_list" type="flowControllerDescriptorListType" minOccurs="0" maxOccurs="1"/>
2266
                            <xs:element name="builtin_controllers_sender_thread" type="threadSettingsType" minOccurs="0" maxOccurs="1"/>
2267
                            <xs:element name="timed_events_thread" type="threadSettingsType" minOccurs="0" maxOccurs="1"/>
2268
                            <xs:element name="discovery_server_thread" type="threadSettingsType" minOccurs="0" maxOccurs="1"/>
2269
                            <xs:element name="typelookup_service_thread" type="threadSettingsType" minOccurs="0" maxOccurs="1"/>
2270
                            <xs:element name="builtin_transports_reception_threads" type="threadSettingsType" minOccurs="0" maxOccurs="1"/>
2271
                            <xs:element name="security_log_thread" type="threadSettingsType" minOccurs="0" maxOccurs="1"/>
2272
                        </xs:all>
2273
                    </xs:complexType>
2274
                </xs:element>
2275
            </xs:all>
2276
        </xs:complexType>
2277
     */
2278
2279
83.2k
    if (nullptr == p_profile)
2280
0
    {
2281
0
        EPROSIMA_LOG_ERROR(XMLPARSER, "Bad parameters!");
2282
0
        return XMLP_ret::XML_ERROR;
2283
0
    }
2284
2285
83.2k
    addAllAttributes(p_profile, participant_node);
2286
2287
83.2k
    uint8_t ident = 1;
2288
83.2k
    tinyxml2::XMLElement* p_element;
2289
83.2k
    tinyxml2::XMLElement* p_aux0 = nullptr;
2290
83.2k
    const char* name = nullptr;
2291
83.2k
    std::set<std::string> tags_present;
2292
2293
    /*
2294
     * The only allowed elements are <domainId> and <rtps>
2295
     *   - The min occurrences of <domainId> are 0, and its max is 1; look for it.
2296
     *   - The min occurrences of <rtps> are 0, and its max is 1; look for it.
2297
     */
2298
135k
    for (p_element = p_profile->FirstChildElement(); p_element != nullptr; p_element = p_element->NextSiblingElement())
2299
54.6k
    {
2300
54.6k
        name = p_element->Name();
2301
54.6k
        if (tags_present.count(name) != 0)
2302
552
        {
2303
552
            EPROSIMA_LOG_ERROR(XMLPARSER, "Duplicated element found in 'participant'. Tag: " << name);
2304
552
            return XMLP_ret::XML_ERROR;
2305
552
        }
2306
54.1k
        tags_present.emplace(name);
2307
2308
54.1k
        if (strcmp(p_element->Name(), DOMAIN_ID) == 0)
2309
1.10k
        {
2310
            // domainId - uint32
2311
1.10k
            if (XMLP_ret::XML_OK != getXMLUint(p_element, &participant_node.get()->domainId, ident))
2312
556
            {
2313
556
                return XMLP_ret::XML_ERROR;
2314
556
            }
2315
1.10k
        }
2316
53.0k
        else if (strcmp(p_element->Name(), RTPS) == 0)
2317
52.0k
        {
2318
52.0k
            p_aux0 = p_element;
2319
52.0k
        }
2320
989
        else
2321
989
        {
2322
989
            EPROSIMA_LOG_ERROR(XMLPARSER, "Found incorrect tag '" << p_element->Name() << "'");
2323
989
            return XMLP_ret::XML_ERROR;
2324
989
        }
2325
54.1k
    }
2326
81.1k
    tags_present.clear();
2327
2328
    // <rtps> is not present, but that's OK
2329
81.1k
    if (nullptr == p_aux0)
2330
29.3k
    {
2331
29.3k
        return XMLP_ret::XML_OK;
2332
29.3k
    }
2333
2334
    // Check contents of <rtps>
2335
58.1k
    for (p_aux0 = p_aux0->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
2336
52.9k
    {
2337
52.9k
        name = p_aux0->Name();
2338
2339
52.9k
        if (tags_present.count(name) != 0)
2340
503
        {
2341
503
            EPROSIMA_LOG_ERROR(XMLPARSER,
2342
503
                    "Duplicated element found in 'rtpsParticipantAttributesType'. Tag: " << name);
2343
503
            return XMLP_ret::XML_ERROR;
2344
503
        }
2345
52.4k
        tags_present.emplace(name);
2346
2347
52.4k
        if (strcmp(name, ALLOCATION) == 0)
2348
310
        {
2349
            // allocation
2350
310
            if (XMLP_ret::XML_OK !=
2351
310
                    getXMLParticipantAllocationAttributes(p_aux0, participant_node.get()->rtps.allocation, ident))
2352
0
            {
2353
0
                return XMLP_ret::XML_ERROR;
2354
0
            }
2355
310
        }
2356
52.1k
        else if (strcmp(name, PREFIX) == 0)
2357
455
        {
2358
            // prefix
2359
455
            if (XMLP_ret::XML_OK !=
2360
455
                    getXMLguidPrefix(p_aux0, participant_node.get()->rtps.prefix, ident))
2361
455
            {
2362
455
                return XMLP_ret::XML_ERROR;
2363
455
            }
2364
455
        }
2365
51.7k
        else if (strcmp(name, IGN_NON_MATCHING_LOCS) == 0)
2366
371
        {
2367
            // ignore_non_matching_locators - boolean
2368
371
            if (XMLP_ret::XML_OK !=
2369
371
                    getXMLBool(p_aux0, &participant_node.get()->rtps.ignore_non_matching_locators, ident))
2370
371
            {
2371
371
                return XMLP_ret::XML_ERROR;
2372
371
            }
2373
371
        }
2374
51.3k
        else if (strcmp(name, DEF_EXT_UNI_LOC_LIST) == 0)
2375
406
        {
2376
            // default_external_unicast_locators - externalLocatorListType
2377
406
            if (XMLP_ret::XML_OK !=
2378
406
                    getXMLExternalLocatorList(p_aux0, participant_node.get()->rtps.default_external_unicast_locators,
2379
406
                    ident))
2380
0
            {
2381
0
                return XMLP_ret::XML_ERROR;
2382
0
            }
2383
406
        }
2384
50.9k
        else if (strcmp(name, DEF_UNI_LOC_LIST) == 0)
2385
225
        {
2386
            // defaultUnicastLocatorList
2387
225
            if (XMLP_ret::XML_OK !=
2388
225
                    getXMLLocatorList(p_aux0, participant_node.get()->rtps.defaultUnicastLocatorList, ident))
2389
225
            {
2390
225
                return XMLP_ret::XML_ERROR;
2391
225
            }
2392
225
        }
2393
50.7k
        else if (strcmp(name, DEF_MULTI_LOC_LIST) == 0)
2394
70
        {
2395
            // defaultMulticastLocatorList
2396
70
            if (XMLP_ret::XML_OK !=
2397
70
                    getXMLLocatorList(p_aux0, participant_node.get()->rtps.defaultMulticastLocatorList, ident))
2398
70
            {
2399
70
                return XMLP_ret::XML_ERROR;
2400
70
            }
2401
70
        }
2402
50.6k
        else if (strcmp(name, SEND_SOCK_BUF_SIZE) == 0)
2403
77
        {
2404
            // sendSocketBufferSize - uint32
2405
77
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &participant_node.get()->rtps.sendSocketBufferSize, ident))
2406
77
            {
2407
77
                return XMLP_ret::XML_ERROR;
2408
77
            }
2409
77
        }
2410
50.5k
        else if (strcmp(name, LIST_SOCK_BUF_SIZE) == 0)
2411
101
        {
2412
            // listenSocketBufferSize - uint32
2413
101
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &participant_node.get()->rtps.listenSocketBufferSize, ident))
2414
101
            {
2415
101
                return XMLP_ret::XML_ERROR;
2416
101
            }
2417
101
        }
2418
50.4k
        else if (strcmp(name, NETMASK_FILTER) == 0)
2419
160
        {
2420
160
            std::string netmask_filter_str;
2421
160
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &netmask_filter_str, 0))
2422
160
            {
2423
160
                EPROSIMA_LOG_ERROR(XMLPARSER, "Invalid element found into 'netmask_filter'.");
2424
160
                return XMLP_ret::XML_ERROR;
2425
160
            }
2426
2427
0
            try
2428
0
            {
2429
0
                participant_node.get()->rtps.netmaskFilter =
2430
0
                        fastdds::rtps::network::netmask_filter::string_to_netmask_filter_kind(netmask_filter_str);
2431
0
            }
2432
0
            catch (const std::invalid_argument& e)
2433
0
            {
2434
0
                EPROSIMA_LOG_ERROR(XMLPARSER, "Invalid element found into 'netmask_filter' : " << e.what());
2435
0
                return XMLP_ret::XML_ERROR;
2436
0
            }
2437
0
        }
2438
50.3k
        else if (strcmp(name, BUILTIN) == 0)
2439
9.30k
        {
2440
            // builtin
2441
9.30k
            if (XMLP_ret::XML_OK != getXMLBuiltinAttributes(p_aux0, participant_node.get()->rtps.builtin, ident))
2442
8.46k
            {
2443
8.46k
                return XMLP_ret::XML_ERROR;
2444
8.46k
            }
2445
9.30k
        }
2446
40.9k
        else if (strcmp(name, PORT) == 0)
2447
1.05k
        {
2448
            // port
2449
1.05k
            if (XMLP_ret::XML_OK != getXMLPortParameters(p_aux0, participant_node.get()->rtps.port, ident))
2450
0
            {
2451
0
                return XMLP_ret::XML_ERROR;
2452
0
            }
2453
1.05k
        }
2454
39.9k
        else if (0 == strcmp(name, USER_DATA))
2455
348
        {
2456
            // userData
2457
348
            if (XMLP_ret::XML_OK != getXMLOctetVector(p_aux0, participant_node.get()->rtps.userData, ident))
2458
0
            {
2459
0
                return XMLP_ret::XML_ERROR;
2460
0
            }
2461
348
        }
2462
39.5k
        else if (strcmp(name, PART_ID) == 0)
2463
840
        {
2464
            // participantID - int32
2465
840
            if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &participant_node.get()->rtps.participantID, ident))
2466
840
            {
2467
840
                return XMLP_ret::XML_ERROR;
2468
840
            }
2469
840
        }
2470
38.7k
        else if (strcmp(name, EASY_MODE_IP) == 0)
2471
84
        {
2472
            // easy_mode_ip - string
2473
84
            std::string str_aux;
2474
84
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &str_aux, ident))
2475
84
            {
2476
84
                return XMLP_ret::XML_ERROR;
2477
84
            }
2478
2479
            // Check that the string is a valid IPv4 address
2480
0
            if (!fastdds::rtps::IPLocator::isIPv4(str_aux))
2481
0
            {
2482
0
                EPROSIMA_LOG_ERROR(XMLPARSER, "'easy_mode_ip' is not a valid IPv4 address.");
2483
0
                return XMLP_ret::XML_ERROR;
2484
0
            }
2485
2486
0
            participant_node.get()->rtps.easy_mode_ip = str_aux;
2487
0
        }
2488
38.6k
        else if (strcmp(name, FLOW_CONTROLLER_DESCRIPTOR_LIST) == 0)
2489
211
        {
2490
            // flow_controller_descriptors
2491
211
            if (XMLP_ret::XML_OK !=
2492
211
                    getXMLFlowControllerDescriptorList(p_aux0, participant_node.get()->rtps.flow_controllers, ident))
2493
211
            {
2494
211
                return XMLP_ret::XML_ERROR;
2495
211
            }
2496
211
        }
2497
38.4k
        else if (strcmp(name, USER_TRANS) == 0)
2498
453
        {
2499
            // userTransports
2500
453
            if (XMLP_ret::XML_OK != getXMLTransports(p_aux0, participant_node.get()->rtps.userTransports, ident))
2501
453
            {
2502
453
                return XMLP_ret::XML_ERROR;
2503
453
            }
2504
453
        }
2505
38.0k
        else if (strcmp(name, USE_BUILTIN_TRANS) == 0)
2506
327
        {
2507
            // useBuiltinTransports - boolean
2508
327
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &participant_node.get()->rtps.useBuiltinTransports, ident))
2509
327
            {
2510
327
                return XMLP_ret::XML_ERROR;
2511
327
            }
2512
327
        }
2513
37.6k
        else if (strcmp(name, BUILTIN_TRANS) == 0)
2514
24.1k
        {
2515
            // builtinTransports
2516
24.1k
            eprosima::fastdds::rtps::BuiltinTransports bt;
2517
24.1k
            eprosima::fastdds::rtps::BuiltinTransportsOptions bt_opts;
2518
24.1k
            if (XMLP_ret::XML_OK != getXMLBuiltinTransports(p_aux0, &bt, &bt_opts, ident))
2519
24.1k
            {
2520
24.1k
                return XMLP_ret::XML_ERROR;
2521
24.1k
            }
2522
0
            participant_node.get()->rtps.setup_transports(bt, bt_opts);
2523
0
        }
2524
13.5k
        else if (strcmp(name, PROPERTIES_POLICY) == 0)
2525
358
        {
2526
            // propertiesPolicy
2527
358
            if (XMLP_ret::XML_OK != getXMLPropertiesPolicy(p_aux0, participant_node.get()->rtps.properties, ident))
2528
0
            {
2529
0
                return XMLP_ret::XML_ERROR;
2530
0
            }
2531
358
        }
2532
13.1k
        else if (strcmp(name, NAME) == 0)
2533
1.90k
        {
2534
            // name - string
2535
1.90k
            std::string s;
2536
1.90k
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident))
2537
858
            {
2538
858
                return XMLP_ret::XML_ERROR;
2539
858
            }
2540
1.04k
            participant_node.get()->rtps.setName(s.c_str());
2541
1.04k
        }
2542
11.2k
        else if (strcmp(name, BUILTIN_CONTROLLERS_SENDER_THREAD) == 0)
2543
2.06k
        {
2544
2.06k
            if (XMLP_ret::XML_OK !=
2545
2.06k
                    getXMLThreadSettings(*p_aux0,
2546
2.06k
                    participant_node.get()->rtps.builtin_controllers_sender_thread))
2547
1.57k
            {
2548
1.57k
                return XMLP_ret::XML_ERROR;
2549
1.57k
            }
2550
2.06k
        }
2551
9.17k
        else if (strcmp(name, TIMED_EVENTS_THREAD) == 0)
2552
544
        {
2553
544
            if (XMLP_ret::XML_OK != getXMLThreadSettings(*p_aux0, participant_node.get()->rtps.timed_events_thread))
2554
74
            {
2555
74
                return XMLP_ret::XML_ERROR;
2556
74
            }
2557
544
        }
2558
8.63k
        else if (strcmp(name, DISCOVERY_SERVER_THREAD) == 0)
2559
504
        {
2560
504
            if (XMLP_ret::XML_OK != getXMLThreadSettings(*p_aux0, participant_node.get()->rtps.discovery_server_thread))
2561
88
            {
2562
88
                return XMLP_ret::XML_ERROR;
2563
88
            }
2564
504
        }
2565
8.13k
        else if (strcmp(name, TYPELOOKUP_SERVICE_THREAD) == 0)
2566
491
        {
2567
491
            if (XMLP_ret::XML_OK !=
2568
491
                    getXMLThreadSettings(*p_aux0, participant_node.get()->rtps.typelookup_service_thread))
2569
273
            {
2570
273
                return XMLP_ret::XML_ERROR;
2571
273
            }
2572
491
        }
2573
7.64k
        else if (strcmp(name, BUILTIN_TRANSPORTS_RECEPTION_THREADS) == 0)
2574
281
        {
2575
281
            if (XMLP_ret::XML_OK !=
2576
281
                    getXMLThreadSettings(*p_aux0,
2577
281
                    participant_node.get()->rtps.builtin_transports_reception_threads))
2578
51
            {
2579
51
                return XMLP_ret::XML_ERROR;
2580
51
            }
2581
281
        }
2582
7.35k
        else if (strcmp(name, SECURITY_LOG_THREAD) == 0)
2583
211
        {
2584
#if HAVE_SECURITY
2585
            if (XMLP_ret::XML_OK != getXMLThreadSettings(*p_aux0, participant_node.get()->rtps.security_log_thread))
2586
            {
2587
                return XMLP_ret::XML_ERROR;
2588
            }
2589
#else
2590
211
            EPROSIMA_LOG_WARNING(XMLPARSER, "Ignoring '" << SECURITY_LOG_THREAD << "' since security is disabled");
2591
211
#endif // if HAVE_SECURITY
2592
211
        }
2593
7.14k
        else
2594
7.14k
        {
2595
7.14k
            EPROSIMA_LOG_ERROR(XMLPARSER, "Invalid element found into 'rtpsParticipantAttributesType'. Name: " << name);
2596
7.14k
            return XMLP_ret::XML_ERROR;
2597
7.14k
        }
2598
52.4k
    }
2599
5.17k
    return XMLP_ret::XML_OK;
2600
51.7k
}
2601
2602
XMLP_ret XMLParser::fillDataNode(
2603
        tinyxml2::XMLElement* p_profile,
2604
        DataNode<fastdds::xmlparser::PublisherAttributes>& publisher_node)
2605
36.1k
{
2606
36.1k
    if (nullptr == p_profile)
2607
0
    {
2608
0
        EPROSIMA_LOG_ERROR(XMLPARSER, "Bad parameters!");
2609
0
        return XMLP_ret::XML_ERROR;
2610
0
    }
2611
2612
36.1k
    addAllAttributes(p_profile, publisher_node);
2613
2614
36.1k
    uint8_t ident = 1;
2615
36.1k
    if (XMLP_ret::XML_OK != getXMLPublisherAttributes(p_profile, *publisher_node.get(), ident))
2616
14.8k
    {
2617
14.8k
        return XMLP_ret::XML_ERROR;
2618
14.8k
    }
2619
2620
21.2k
    return XMLP_ret::XML_OK;
2621
36.1k
}
2622
2623
XMLP_ret XMLParser::fillDataNode(
2624
        tinyxml2::XMLElement* p_profile,
2625
        DataNode<fastdds::xmlparser::SubscriberAttributes>& subscriber_node)
2626
61.4k
{
2627
61.4k
    if (nullptr == p_profile)
2628
0
    {
2629
0
        EPROSIMA_LOG_ERROR(XMLPARSER, "Bad parameters!");
2630
0
        return XMLP_ret::XML_ERROR;
2631
0
    }
2632
2633
61.4k
    addAllAttributes(p_profile, subscriber_node);
2634
2635
61.4k
    uint8_t ident = 1;
2636
61.4k
    if (XMLP_ret::XML_OK != getXMLSubscriberAttributes(p_profile, *subscriber_node.get(), ident))
2637
15.0k
    {
2638
15.0k
        return XMLP_ret::XML_ERROR;
2639
15.0k
    }
2640
2641
46.4k
    return XMLP_ret::XML_OK;
2642
61.4k
}
2643
2644
XMLP_ret XMLParser::fillDataNode(
2645
        tinyxml2::XMLElement* p_profile,
2646
        DataNode<fastdds::xmlparser::RequesterAttributes>& requester_node)
2647
12.0k
{
2648
    /*
2649
        <xs:complexType name="replierRequesterProfileType">
2650
            <xs:all minOccurs="0">
2651
                <xs:element name="request_topic_name" type="string" minOccurs="0"/>
2652
                <xs:element name="reply_topic_name" type="string" minOccurs="0"/>
2653
                <xs:element name="data_writer" type="publisherProfileNoAttributesType" minOccurs="0"/>
2654
                <xs:element name="data_reader" type="subscriberProfileNoAttributesType" minOccurs="0"/>
2655
            </xs:all>
2656
            <xs:attribute name="profile_name" type="string" use="required"/>
2657
            <xs:attribute name="service_name" type="string" use="required"/>
2658
            <xs:attribute name="request_type" type="string" use="required"/>
2659
            <xs:attribute name="reply_type" type="string" use="required"/>
2660
        </xs:complexType>
2661
     */
2662
2663
12.0k
    if (nullptr == p_profile)
2664
0
    {
2665
0
        EPROSIMA_LOG_ERROR(XMLPARSER, "Bad parameters!");
2666
0
        return XMLP_ret::XML_ERROR;
2667
0
    }
2668
2669
12.0k
    addAllAttributes(p_profile, requester_node);
2670
12.0k
    auto found_attributes = requester_node.getAttributes();
2671
2672
12.0k
    auto it_attributes = found_attributes.find(SERVICE_NAME);
2673
12.0k
    if (found_attributes.end() != it_attributes)
2674
10.3k
    {
2675
10.3k
        requester_node.get()->service_name = it_attributes->second;
2676
10.3k
        requester_node.get()->request_topic_name = it_attributes->second + "_Request";
2677
10.3k
        requester_node.get()->reply_topic_name = it_attributes->second + "_Reply";
2678
10.3k
    }
2679
1.70k
    else
2680
1.70k
    {
2681
1.70k
        EPROSIMA_LOG_ERROR(XMLPARSER, "Not found required attribute " << SERVICE_NAME);
2682
1.70k
        return XMLP_ret::XML_ERROR;
2683
1.70k
    }
2684
2685
10.3k
    it_attributes = found_attributes.find(REQUEST_TYPE);
2686
10.3k
    if (found_attributes.end() != it_attributes)
2687
8.53k
    {
2688
8.53k
        requester_node.get()->request_type = it_attributes->second;
2689
8.53k
    }
2690
1.80k
    else
2691
1.80k
    {
2692
1.80k
        EPROSIMA_LOG_ERROR(XMLPARSER, "Not found required attribute " << REQUEST_TYPE);
2693
1.80k
        return XMLP_ret::XML_ERROR;
2694
1.80k
    }
2695
2696
8.53k
    it_attributes = found_attributes.find(REPLY_TYPE);
2697
8.53k
    if (found_attributes.end() != it_attributes)
2698
8.17k
    {
2699
8.17k
        requester_node.get()->reply_type = it_attributes->second;
2700
8.17k
    }
2701
359
    else
2702
359
    {
2703
359
        EPROSIMA_LOG_ERROR(XMLPARSER, "Not found required attribute " << REPLY_TYPE);
2704
359
        return XMLP_ret::XML_ERROR;
2705
359
    }
2706
2707
8.17k
    uint8_t ident = 1;
2708
8.17k
    tinyxml2::XMLElement* p_aux0 = nullptr;
2709
8.17k
    const char* name = nullptr;
2710
2711
9.50k
    for (p_aux0 = p_profile->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
2712
2.68k
    {
2713
2.68k
        name = p_aux0->Name();
2714
2.68k
        if (strcmp(name, REQUEST_TOPIC_NAME) == 0)
2715
74
        {
2716
74
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &requester_node.get()->request_topic_name, ident))
2717
74
            {
2718
74
                return XMLP_ret::XML_ERROR;
2719
74
            }
2720
74
        }
2721
2.61k
        else if (strcmp(name, REPLY_TOPIC_NAME) == 0)
2722
341
        {
2723
341
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &requester_node.get()->reply_topic_name, ident))
2724
341
            {
2725
341
                return XMLP_ret::XML_ERROR;
2726
341
            }
2727
341
        }
2728
2.27k
        else if (strcmp(name, PUBLISHER) == 0 || strcmp(name, DATA_WRITER) == 0)
2729
551
        {
2730
551
            if (XMLP_ret::XML_OK != getXMLPublisherAttributes(p_aux0, requester_node.get()->publisher, ident))
2731
10
            {
2732
10
                return XMLP_ret::XML_ERROR;
2733
10
            }
2734
551
        }
2735
1.72k
        else if (strcmp(name, SUBSCRIBER) == 0 || strcmp(name, DATA_READER) == 0)
2736
859
        {
2737
859
            if (XMLP_ret::XML_OK != getXMLSubscriberAttributes(p_aux0, requester_node.get()->subscriber, ident))
2738
69
            {
2739
69
                return XMLP_ret::XML_ERROR;
2740
69
            }
2741
859
        }
2742
861
        else
2743
861
        {
2744
861
            EPROSIMA_LOG_ERROR(XMLPARSER, "Not expected tag: '" << name << "'");
2745
861
            return XMLP_ret::XML_ERROR;
2746
861
        }
2747
2748
2.68k
    }
2749
2750
6.82k
    requester_node.get()->publisher.topic.topicDataType = requester_node.get()->request_type;
2751
6.82k
    requester_node.get()->publisher.topic.topicName = requester_node.get()->request_topic_name;
2752
2753
6.82k
    requester_node.get()->subscriber.topic.topicDataType = requester_node.get()->reply_type;
2754
6.82k
    requester_node.get()->subscriber.topic.topicName = requester_node.get()->reply_topic_name;
2755
2756
6.82k
    return XMLP_ret::XML_OK;
2757
8.17k
}
2758
2759
XMLP_ret XMLParser::fillDataNode(
2760
        tinyxml2::XMLElement* p_profile,
2761
        DataNode<fastdds::xmlparser::ReplierAttributes>& replier_node)
2762
12.6k
{
2763
    /*
2764
        <xs:complexType name="replierRequesterProfileType">
2765
            <xs:all minOccurs="0">
2766
                <xs:element name="request_topic_name" type="string" minOccurs="0"/>
2767
                <xs:element name="reply_topic_name" type="string" minOccurs="0"/>
2768
                <xs:element name="data_writer" type="publisherProfileNoAttributesType" minOccurs="0"/>
2769
                <xs:element name="data_reader" type="subscriberProfileNoAttributesType" minOccurs="0"/>
2770
            </xs:all>
2771
            <xs:attribute name="profile_name" type="string" use="required"/>
2772
            <xs:attribute name="service_name" type="string" use="required"/>
2773
            <xs:attribute name="request_type" type="string" use="required"/>
2774
            <xs:attribute name="reply_type" type="string" use="required"/>
2775
        </xs:complexType>
2776
     */
2777
2778
12.6k
    if (nullptr == p_profile)
2779
0
    {
2780
0
        EPROSIMA_LOG_ERROR(XMLPARSER, "Bad parameters!");
2781
0
        return XMLP_ret::XML_ERROR;
2782
0
    }
2783
2784
12.6k
    addAllAttributes(p_profile, replier_node);
2785
12.6k
    auto found_attributes = replier_node.getAttributes();
2786
2787
12.6k
    auto it_attributes = found_attributes.find(SERVICE_NAME);
2788
12.6k
    if (found_attributes.end() != it_attributes)
2789
8.72k
    {
2790
8.72k
        replier_node.get()->service_name = it_attributes->second;
2791
8.72k
        replier_node.get()->request_topic_name = it_attributes->second + "_Request";
2792
8.72k
        replier_node.get()->reply_topic_name = it_attributes->second + "_Reply";
2793
8.72k
    }
2794
3.87k
    else
2795
3.87k
    {
2796
3.87k
        EPROSIMA_LOG_ERROR(XMLPARSER, "Not found required attribute " << SERVICE_NAME);
2797
3.87k
        return XMLP_ret::XML_ERROR;
2798
3.87k
    }
2799
2800
8.72k
    it_attributes = found_attributes.find(REQUEST_TYPE);
2801
8.72k
    if (found_attributes.end() != it_attributes)
2802
7.39k
    {
2803
7.39k
        replier_node.get()->request_type = it_attributes->second;
2804
7.39k
    }
2805
1.32k
    else
2806
1.32k
    {
2807
1.32k
        EPROSIMA_LOG_ERROR(XMLPARSER, "Not found required attribute " << REQUEST_TYPE);
2808
1.32k
        return XMLP_ret::XML_ERROR;
2809
1.32k
    }
2810
2811
7.39k
    it_attributes = found_attributes.find(REPLY_TYPE);
2812
7.39k
    if (found_attributes.end() != it_attributes)
2813
6.91k
    {
2814
6.91k
        replier_node.get()->reply_type = it_attributes->second;
2815
6.91k
    }
2816
482
    else
2817
482
    {
2818
482
        EPROSIMA_LOG_ERROR(XMLPARSER, "Not found required attribute " << REPLY_TYPE);
2819
482
        return XMLP_ret::XML_ERROR;
2820
482
    }
2821
2822
6.91k
    uint8_t ident = 1;
2823
6.91k
    tinyxml2::XMLElement* p_aux0 = nullptr;
2824
6.91k
    const char* name = nullptr;
2825
2826
8.23k
    for (p_aux0 = p_profile->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
2827
2.80k
    {
2828
2.80k
        name = p_aux0->Name();
2829
2.80k
        if (strcmp(name, REQUEST_TOPIC_NAME) == 0)
2830
204
        {
2831
204
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &replier_node.get()->request_topic_name, ident))
2832
204
            {
2833
204
                return XMLP_ret::XML_ERROR;
2834
204
            }
2835
204
        }
2836
2.60k
        else if (strcmp(name, REPLY_TOPIC_NAME) == 0)
2837
208
        {
2838
208
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &replier_node.get()->reply_topic_name, ident))
2839
208
            {
2840
208
                return XMLP_ret::XML_ERROR;
2841
208
            }
2842
208
        }
2843
2.39k
        else if (strcmp(name, PUBLISHER) == 0 || strcmp(name, DATA_WRITER) == 0)
2844
507
        {
2845
507
            if (XMLP_ret::XML_OK != getXMLPublisherAttributes(p_aux0, replier_node.get()->publisher, ident))
2846
10
            {
2847
10
                return XMLP_ret::XML_ERROR;
2848
10
            }
2849
507
        }
2850
1.89k
        else if (strcmp(name, SUBSCRIBER) == 0 || strcmp(name, DATA_READER) == 0)
2851
1.02k
        {
2852
1.02k
            if (XMLP_ret::XML_OK != getXMLSubscriberAttributes(p_aux0, replier_node.get()->subscriber, ident))
2853
196
            {
2854
196
                return XMLP_ret::XML_ERROR;
2855
196
            }
2856
1.02k
        }
2857
864
        else
2858
864
        {
2859
864
            EPROSIMA_LOG_ERROR(XMLPARSER, "Not expected tag: '" << name << "'");
2860
864
            return XMLP_ret::XML_ERROR;
2861
864
        }
2862
2.80k
    }
2863
2864
5.43k
    replier_node.get()->subscriber.topic.topicDataType = replier_node.get()->request_type;
2865
5.43k
    replier_node.get()->subscriber.topic.topicName = replier_node.get()->request_topic_name;
2866
2867
5.43k
    replier_node.get()->publisher.topic.topicDataType = replier_node.get()->reply_type;
2868
5.43k
    replier_node.get()->publisher.topic.topicName = replier_node.get()->reply_topic_name;
2869
2870
5.43k
    return XMLP_ret::XML_OK;
2871
6.91k
}
2872
2873
} // namespace xmlparser
2874
} // namespace fastdds
2875
} // namespace eprosima