Coverage Report

Created: 2022-08-24 06:19

/src/Fast-DDS/src/cpp/rtps/xmlparser/XMLParser.cpp
Line
Count
Source (jump to first uncovered line)
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 <fastrtps/xmlparser/XMLParser.h>
16
#include <fastrtps/xmlparser/XMLParserCommon.h>
17
#include <fastrtps/xmlparser/XMLTree.h>
18
19
#include <fastrtps/transport/UDPv4TransportDescriptor.h>
20
#include <fastrtps/transport/UDPv6TransportDescriptor.h>
21
#include <fastrtps/transport/TCPv4TransportDescriptor.h>
22
#include <fastrtps/transport/TCPv6TransportDescriptor.h>
23
#include <fastdds/rtps/transport/shared_mem/SharedMemTransportDescriptor.h>
24
25
#include <fastrtps/xmlparser/XMLProfileManager.h>
26
27
#include <fastdds/dds/log/FileConsumer.hpp>
28
#include <fastdds/dds/log/StdoutConsumer.hpp>
29
#include <fastdds/dds/log/StdoutErrConsumer.hpp>
30
31
#include <tinyxml2.h>
32
#include <iostream>
33
#include <cstdlib>
34
35
namespace eprosima {
36
namespace fastrtps {
37
namespace xmlparser {
38
39
XMLP_ret XMLParser::loadDefaultXMLFile(
40
        up_base_node_t& root)
41
0
{
42
0
    return loadXML(DEFAULT_FASTRTPS_PROFILES, root);
43
0
}
44
45
XMLP_ret XMLParser::parseXML(
46
        tinyxml2::XMLDocument& xmlDoc,
47
        up_base_node_t& root)
48
18.7k
{
49
18.7k
    XMLP_ret ret = XMLP_ret::XML_OK;
50
18.7k
    tinyxml2::XMLElement* p_root = xmlDoc.FirstChildElement(ROOT);
51
18.7k
    if (nullptr == p_root)
52
11.8k
    {
53
        // Just profiles in the XML.
54
11.8k
        if (nullptr == (p_root = xmlDoc.FirstChildElement(PROFILES)))
55
3.22k
        {
56
            // Just types in the XML.
57
3.22k
            if (nullptr == (p_root = xmlDoc.FirstChildElement(TYPES)))
58
232
            {
59
                // Just log config in the XML.
60
232
                if (nullptr == (p_root = xmlDoc.FirstChildElement(LOG)))
61
71
                {
62
                    // Just library_settings config in the XML.
63
71
                    if (nullptr == (p_root = xmlDoc.FirstChildElement(LIBRARY_SETTINGS)))
64
70
                    {
65
70
                        logError(XMLPARSER, "Not found root tag");
66
70
                        ret = XMLP_ret::XML_ERROR;
67
70
                    }
68
1
                    else
69
1
                    {
70
1
                        root.reset(new BaseNode{NodeType::LIBRARY_SETTINGS});
71
1
                        ret  = parseXMLLibrarySettings(p_root);
72
1
                    }
73
71
                }
74
161
                else
75
161
                {
76
161
                    root.reset(new BaseNode{NodeType::LOG});
77
161
                    ret  = parseLogConfig(p_root);
78
161
                }
79
232
            }
80
2.99k
            else
81
2.99k
            {
82
2.99k
                root.reset(new BaseNode{ NodeType::TYPES });
83
2.99k
                ret = parseDynamicTypes(p_root);
84
2.99k
            }
85
3.22k
        }
86
8.62k
        else
87
8.62k
        {
88
8.62k
            root.reset(new BaseNode{ NodeType::PROFILES });
89
8.62k
            ret = parseProfiles(p_root, *root);
90
8.62k
        }
91
11.8k
    }
92
6.86k
    else
93
6.86k
    {
94
6.86k
        root.reset(new BaseNode{ NodeType::ROOT });
95
6.86k
        tinyxml2::XMLElement* node = p_root->FirstChildElement();
96
6.86k
        const char* tag = nullptr;
97
21.0k
        while ((nullptr != node) && (ret == XMLP_ret::XML_OK))
98
14.1k
        {
99
14.1k
            if (nullptr != (tag = node->Value()))
100
14.1k
            {
101
14.1k
                if (strcmp(tag, PROFILES) == 0)
102
1.33k
                {
103
1.33k
                    up_base_node_t profiles_node = up_base_node_t{ new BaseNode{NodeType::PROFILES} };
104
1.33k
                    if (XMLP_ret::XML_OK == (ret = parseProfiles(node, *profiles_node)))
105
1.32k
                    {
106
1.32k
                        root->addChild(std::move(profiles_node));
107
1.32k
                    }
108
1.33k
                }
109
12.7k
                else if (strcmp(tag, LIBRARY_SETTINGS) == 0)
110
1
                {
111
                    // TODO Workaround to propagate the return code upstream. A refactor is needed to propagate the
112
                    // return code in some other more sensible way or populate the object and change code upstream to
113
                    // read this new object.
114
1
                    up_base_node_t library_node = up_base_node_t{ new BaseNode{NodeType::LIBRARY_SETTINGS} };
115
1
                    if (XMLP_ret::XML_OK == (ret = parseXMLLibrarySettings(node)))
116
0
                    {
117
0
                        root->addChild(std::move(library_node));
118
0
                    }
119
1
                }
120
12.7k
                else if (strcmp(tag, PARTICIPANT) == 0)
121
744
                {
122
744
                    ret = parseXMLParticipantProf(node, *root);
123
744
                }
124
12.0k
                else if (strcmp(tag, PUBLISHER) == 0 || strcmp(tag, DATA_WRITER) == 0)
125
2.94k
                {
126
2.94k
                    ret = parseXMLPublisherProf(node, *root);
127
2.94k
                }
128
9.10k
                else if (strcmp(tag, SUBSCRIBER) == 0 || strcmp(tag, DATA_READER) == 0)
129
3.21k
                {
130
3.21k
                    ret = parseXMLSubscriberProf(node, *root);
131
3.21k
                }
132
5.89k
                else if (strcmp(tag, TOPIC) == 0)
133
1.50k
                {
134
1.50k
                    ret = parseXMLTopicData(node, *root);
135
1.50k
                }
136
4.38k
                else if (strcmp(tag, REQUESTER) == 0)
137
431
                {
138
431
                    ret = parseXMLRequesterProf(node, *root);
139
431
                }
140
3.95k
                else if (strcmp(tag, REPLIER) == 0)
141
515
                {
142
515
                    ret = parseXMLReplierProf(node, *root);
143
515
                }
144
3.43k
                else if (strcmp(tag, TYPES) == 0)
145
462
                {
146
                    // TODO Workaround to propagate the return code upstream. A refactor is needed to propagate the
147
                    // return code in some other more sensible way or populate the object and change code upstream to
148
                    // read this new object.
149
462
                    up_base_node_t types_node = up_base_node_t{ new BaseNode{NodeType::TYPES} };
150
462
                    if (XMLP_ret::XML_OK == (ret = parseXMLTypes(node)))
151
461
                    {
152
461
                        root->addChild(std::move(types_node));
153
461
                    }
154
462
                }
155
2.97k
                else if (strcmp(tag, LOG) == 0)
156
2.16k
                {
157
                    // TODO Workaround to propagate the return code upstream. A refactor is needed to propagate the
158
                    // return code in some other more sensible way or populate the object and change code upstream to
159
                    // read this new object.
160
2.16k
                    up_base_node_t log_node = up_base_node_t{ new BaseNode{NodeType::LOG} };
161
2.16k
                    if (XMLP_ret::XML_OK == (ret = parseLogConfig(node)))
162
2.14k
                    {
163
2.14k
                        root->addChild(std::move(log_node));
164
2.14k
                    }
165
2.16k
                }
166
813
                else
167
813
                {
168
813
                    logError(XMLPARSER, "Not expected tag: '" << tag << "'");
169
813
                    ret = XMLP_ret::XML_ERROR;
170
813
                }
171
14.1k
            }
172
173
14.1k
            node = node->NextSiblingElement();
174
14.1k
        }
175
6.86k
    }
176
18.7k
    return ret;
177
18.7k
}
178
179
XMLP_ret XMLParser::parseXMLProfiles(
180
        tinyxml2::XMLElement& profiles,
181
        up_base_node_t& root)
182
0
{
183
0
    XMLP_ret ret = XMLP_ret::XML_OK;
184
0
    root.reset(new BaseNode{NodeType::PROFILES});
185
0
    ret  = parseProfiles(&profiles, *root);
186
0
    return ret;
187
0
}
188
189
XMLP_ret XMLParser::parseXMLTransportsProf(
190
        tinyxml2::XMLElement* p_root)
191
360
{
192
    /*
193
        <xs:complexType name="TransportDescriptorListType">
194
            <xs:sequence>
195
                <xs:element name="transport_descriptor" type="rtpsTransportDescriptorType"/>
196
            </xs:sequence>
197
        </xs:complexType>
198
     */
199
200
360
    XMLP_ret ret = XMLP_ret::XML_OK;
201
360
    tinyxml2::XMLElement* p_element = p_root->FirstChildElement(TRANSPORT_DESCRIPTOR);
202
360
    while (p_element != nullptr)
203
0
    {
204
0
        ret = parseXMLTransportData(p_element);
205
0
        if (ret != XMLP_ret::XML_OK)
206
0
        {
207
0
            logError(XMLPARSER, "Error parsing transports");
208
0
            return ret;
209
0
        }
210
0
        p_element = p_element->NextSiblingElement(TRANSPORT_DESCRIPTOR);
211
0
    }
212
360
    return ret;
213
360
}
214
215
XMLP_ret XMLParser::parseXMLTransportData(
216
        tinyxml2::XMLElement* p_root)
217
0
{
218
    /*
219
        <xs:complexType name="rtpsTransportDescriptorType">
220
            <xs:all minOccurs="0">
221
                <xs:element name="transport_id" type="stringType"/>
222
                <xs:element name="type" type="stringType"/>
223
                <xs:element name="sendBufferSize" type="int32Type" minOccurs="0" maxOccurs="1"/>
224
                <xs:element name="receiveBufferSize" type="int32Type" minOccurs="0" maxOccurs="1"/>
225
                <xs:element name="TTL" type="uint8Type" minOccurs="0" maxOccurs="1"/>
226
                <xs:element name="non_blocking_send" type="boolType" minOccurs="0" maxOccurs="1"/>
227
                <xs:element name="maxMessageSize" type="uint32Type" minOccurs="0" maxOccurs="1"/>
228
                <xs:element name="maxInitialPeersRange" type="uint32Type" minOccurs="0" maxOccurs="1"/>
229
                <xs:element name="interfaceWhiteList" type="stringListType" minOccurs="0" maxOccurs="1"/>
230
                <xs:element name="wan_addr" type="stringType" minOccurs="0" maxOccurs="1"/>
231
                <xs:element name="output_port" type="uint16Type" minOccurs="0" maxOccurs="1"/>
232
                <xs:element name="keep_alive_frequency_ms" type="uint32Type" minOccurs="0" maxOccurs="1"/>
233
                <xs:element name="keep_alive_timeout_ms" type="uint32Type" minOccurs="0" maxOccurs="1"/>
234
                <xs:element name="max_logical_port" type="uint16Type" minOccurs="0" maxOccurs="1"/>
235
                <xs:element name="logical_port_range" type="uint16Type" minOccurs="0" maxOccurs="1"/>
236
                <xs:element name="logical_port_increment" type="uint16Type" minOccurs="0" maxOccurs="1"/>
237
                <xs:element name="metadata_logical_port" type="uint16Type" minOccurs="0" maxOccurs="1"/>
238
                <xs:element name="listening_ports" type="portListType" minOccurs="0" maxOccurs="1"/>
239
                <xs:element name="calculate_crc" type="boolType" minOccurs="0" maxOccurs="1"/>
240
                <xs:element name="check_crc" type="boolType" minOccurs="0" maxOccurs="1"/>
241
                <xs:element name="enable_tcp_nodelay" type="boolType" minOccurs="0" maxOccurs="1"/>
242
                <xs:element name="tls" type="tlsConfigType" minOccurs="0" maxOccurs="1"/>
243
            </xs:all>
244
        </xs:complexType>
245
     */
246
247
0
    XMLP_ret ret = XMLP_ret::XML_OK;
248
0
    std::string sId = "";
249
0
    sp_transport_t pDescriptor = nullptr;
250
251
0
    tinyxml2::XMLElement* p_aux0 = nullptr;
252
0
    p_aux0 = p_root->FirstChildElement(TRANSPORT_ID);
253
0
    if (nullptr == p_aux0)
254
0
    {
255
0
        logError(XMLPARSER, "Not found '" << TRANSPORT_ID << "' attribute");
256
0
        return XMLP_ret::XML_ERROR;
257
0
    }
258
0
    else
259
0
    {
260
0
        if (p_aux0->GetText() != nullptr)
261
0
        {
262
0
            sId = p_aux0->GetText();
263
0
        }
264
0
        else
265
0
        {
266
0
            logError(XMLPARSER, "'" << TRANSPORT_ID << "' attribute cannot be empty");
267
0
            return XMLP_ret::XML_ERROR;
268
0
        }
269
0
    }
270
271
0
    p_aux0 = p_root->FirstChildElement(TYPE);
272
0
    if (nullptr == p_aux0)
273
0
    {
274
0
        logError(XMLPARSER, "Not found '" << TYPE << "' attribute");
275
0
        return XMLP_ret::XML_ERROR;
276
0
    }
277
0
    else
278
0
    {
279
0
        std::string sType;
280
0
        if (p_aux0->GetText() != nullptr)
281
0
        {
282
0
            sType = p_aux0->GetText();
283
0
        }
284
0
        else
285
0
        {
286
0
            logError(XMLPARSER, "'" << TYPE << "' attribute cannot be empty");
287
0
            return XMLP_ret::XML_ERROR;
288
0
        }
289
290
0
        if (sType == UDPv4 || sType == UDPv6)
291
0
        {
292
0
            if (sType == UDPv4)
293
0
            {
294
0
                pDescriptor = std::make_shared<rtps::UDPv4TransportDescriptor>();
295
0
            }
296
0
            else
297
0
            {
298
0
                pDescriptor = std::make_shared<rtps::UDPv6TransportDescriptor>();
299
0
            }
300
301
0
            std::shared_ptr<rtps::UDPTransportDescriptor> pUDPDesc =
302
0
                    std::dynamic_pointer_cast<rtps::UDPTransportDescriptor>(pDescriptor);
303
            // Output UDP Socket
304
0
            if (nullptr != (p_aux0 = p_root->FirstChildElement(UDP_OUTPUT_PORT)))
305
0
            {
306
0
                int iSocket = 0;
307
0
                if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iSocket, 0) || iSocket < 0 || iSocket > 65535)
308
0
                {
309
0
                    return XMLP_ret::XML_ERROR;
310
0
                }
311
0
                pUDPDesc->m_output_udp_socket = static_cast<uint16_t>(iSocket);
312
0
            }
313
            // Non-blocking send
314
0
            if (nullptr != (p_aux0 = p_root->FirstChildElement(NON_BLOCKING_SEND)))
315
0
            {
316
0
                if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &pUDPDesc->non_blocking_send, 0))
317
0
                {
318
0
                    return XMLP_ret::XML_ERROR;
319
0
                }
320
0
            }
321
0
        }
322
0
        else if (sType == TCPv4)
323
0
        {
324
0
            pDescriptor = std::make_shared<rtps::TCPv4TransportDescriptor>();
325
0
            ret = parseXMLCommonTCPTransportData(p_root, pDescriptor);
326
0
            if (ret != XMLP_ret::XML_OK)
327
0
            {
328
0
                return ret;
329
0
            }
330
0
            else
331
0
            {
332
0
                std::shared_ptr<rtps::TCPv4TransportDescriptor> pTCPv4Desc =
333
0
                        std::dynamic_pointer_cast<rtps::TCPv4TransportDescriptor>(pDescriptor);
334
335
                // Wan Address
336
0
                if (nullptr != (p_aux0 = p_root->FirstChildElement(TCP_WAN_ADDR)))
337
0
                {
338
0
                    std::string s;
339
0
                    if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, 0))
340
0
                    {
341
0
                        return XMLP_ret::XML_ERROR;
342
0
                    }
343
0
                    pTCPv4Desc->set_WAN_address(s);
344
0
                }
345
0
            }
346
0
        }
347
0
        else if (sType == TCPv6)
348
0
        {
349
0
            pDescriptor = std::make_shared<rtps::TCPv6TransportDescriptor>();
350
0
            ret = parseXMLCommonTCPTransportData(p_root, pDescriptor);
351
0
            if (ret != XMLP_ret::XML_OK)
352
0
            {
353
0
                return ret;
354
0
            }
355
0
        }
356
0
        else if (sType == SHM)
357
0
        {
358
0
            pDescriptor = std::make_shared<fastdds::rtps::SharedMemTransportDescriptor>();
359
0
            ret = parseXMLCommonSharedMemTransportData(p_root, pDescriptor);
360
0
            if (ret != XMLP_ret::XML_OK)
361
0
            {
362
0
                return ret;
363
0
            }
364
0
        }
365
0
        else
366
0
        {
367
0
            logError(XMLPARSER, "Invalid transport type: '" << sType << "'");
368
0
            return XMLP_ret::XML_ERROR;
369
0
        }
370
371
0
        if (sType != SHM)
372
0
        {
373
0
            ret = parseXMLCommonTransportData(p_root, pDescriptor);
374
0
            if (ret != XMLP_ret::XML_OK)
375
0
            {
376
0
                return ret;
377
0
            }
378
0
        }
379
380
0
        XMLProfileManager::insertTransportById(sId, pDescriptor);
381
0
    }
382
0
    return ret;
383
0
}
384
385
XMLP_ret XMLParser::parseXMLCommonTransportData(
386
        tinyxml2::XMLElement* p_root,
387
        sp_transport_t p_transport)
388
0
{
389
    /*
390
        <xs:complexType name="rtpsTransportDescriptorType">
391
            <xs:all minOccurs="0">
392
                <xs:element name="transport_id" type="stringType"/>
393
                <xs:element name="type" type="stringType"/>
394
                <xs:element name="sendBufferSize" type="int32Type" minOccurs="0" maxOccurs="1"/>
395
                <xs:element name="receiveBufferSize" type="int32Type" minOccurs="0" maxOccurs="1"/>
396
                <xs:element name="TTL" type="uint8Type" minOccurs="0" maxOccurs="1"/>
397
                <xs:element name="maxMessageSize" type="uint32Type" minOccurs="0" maxOccurs="1"/>
398
                <xs:element name="maxInitialPeersRange" type="uint32Type" minOccurs="0" maxOccurs="1"/>
399
                <xs:element name="interfaceWhiteList" type="addressListType" minOccurs="0" maxOccurs="1"/>
400
                <xs:element name="wan_addr" type="stringType" minOccurs="0" maxOccurs="1"/>
401
                <xs:element name="output_port" type="uint16Type" minOccurs="0" maxOccurs="1"/>
402
                <xs:element name="keep_alive_frequency_ms" type="uint32Type" minOccurs="0" maxOccurs="1"/>
403
                <xs:element name="keep_alive_timeout_ms" type="uint32Type" minOccurs="0" maxOccurs="1"/>
404
                <xs:element name="max_logical_port" type="uint16Type" minOccurs="0" maxOccurs="1"/>
405
                <xs:element name="logical_port_range" type="uint16Type" minOccurs="0" maxOccurs="1"/>
406
                <xs:element name="logical_port_increment" type="uint16Type" minOccurs="0" maxOccurs="1"/>
407
                <xs:element name="metadata_logical_port" type="uint16Type" minOccurs="0" maxOccurs="1"/>
408
                <xs:element name="listening_ports" type="portListType" minOccurs="0" maxOccurs="1"/>
409
            </xs:all>
410
        </xs:complexType>
411
     */
412
413
0
    std::shared_ptr<rtps::SocketTransportDescriptor> pDesc =
414
0
            std::dynamic_pointer_cast<rtps::SocketTransportDescriptor>(p_transport);
415
416
0
    tinyxml2::XMLElement* p_aux0 = nullptr;
417
0
    const char* name = nullptr;
418
0
    for (p_aux0 = p_root->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
419
0
    {
420
0
        name = p_aux0->Name();
421
0
        if (strcmp(name, SEND_BUFFER_SIZE) == 0)
422
0
        {
423
            // sendBufferSize - int32Type
424
0
            uint32_t iSize = 0;
425
0
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &iSize, 0))
426
0
            {
427
0
                return XMLP_ret::XML_ERROR;
428
0
            }
429
0
            pDesc->sendBufferSize = iSize;
430
0
        }
431
0
        else if (strcmp(name, RECEIVE_BUFFER_SIZE) == 0)
432
0
        {
433
            // receiveBufferSize - int32Type
434
0
            uint32_t iSize = 0;
435
0
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &iSize, 0))
436
0
            {
437
0
                return XMLP_ret::XML_ERROR;
438
0
            }
439
0
            pDesc->receiveBufferSize = iSize;
440
0
        }
441
0
        else if (strcmp(name, TTL) == 0)
442
0
        {
443
            // TTL - int8Type
444
0
            int iTTL = 0;
445
0
            if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iTTL, 0) || iTTL < 0 || iTTL > 255)
446
0
            {
447
0
                return XMLP_ret::XML_ERROR;
448
0
            }
449
0
            pDesc->TTL = static_cast<uint8_t>(iTTL);
450
0
        }
451
0
        else if (strcmp(name, MAX_MESSAGE_SIZE) == 0)
452
0
        {
453
            // maxMessageSize - uint32Type
454
0
            uint32_t uSize = 0;
455
0
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &uSize, 0))
456
0
            {
457
0
                return XMLP_ret::XML_ERROR;
458
0
            }
459
0
            std::dynamic_pointer_cast<rtps::TransportDescriptorInterface>(p_transport)->maxMessageSize = uSize;
460
0
        }
461
0
        else if (strcmp(name, MAX_INITIAL_PEERS_RANGE) == 0)
462
0
        {
463
            // maxInitialPeersRange - uint32Type
464
0
            uint32_t uRange = 0;
465
0
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &uRange, 0))
466
0
            {
467
0
                return XMLP_ret::XML_ERROR;
468
0
            }
469
0
            pDesc->maxInitialPeersRange = uRange;
470
0
        }
471
0
        else if (strcmp(name, WHITE_LIST) == 0)
472
0
        {
473
            // InterfaceWhiteList addressListType
474
0
            const char* address = nullptr;
475
0
            for (tinyxml2::XMLElement* p_aux1 = p_aux0->FirstChildElement();
476
0
                    p_aux1 != nullptr; p_aux1 = p_aux1->NextSiblingElement())
477
0
            {
478
0
                address = p_aux1->Name();
479
0
                if (strcmp(address, ADDRESS) == 0)
480
0
                {
481
0
                    const char* text = p_aux1->GetText();
482
0
                    if (nullptr != text)
483
0
                    {
484
0
                        pDesc->interfaceWhiteList.emplace_back(text);
485
0
                    }
486
0
                }
487
0
                else
488
0
                {
489
0
                    logError(XMLPARSER, "Invalid element found into 'interfaceWhiteList'. Name: " << address);
490
0
                    return XMLP_ret::XML_ERROR;
491
0
                }
492
0
            }
493
0
        }
494
0
        else if (strcmp(name, TCP_WAN_ADDR) == 0 || strcmp(name, UDP_OUTPUT_PORT) == 0 ||
495
0
                strcmp(name, TRANSPORT_ID) == 0 || strcmp(name, TYPE) == 0 ||
496
0
                strcmp(name, KEEP_ALIVE_FREQUENCY) == 0 || strcmp(name, KEEP_ALIVE_TIMEOUT) == 0 ||
497
0
                strcmp(name, MAX_LOGICAL_PORT) == 0 || strcmp(name, LOGICAL_PORT_RANGE) == 0 ||
498
0
                strcmp(name, LOGICAL_PORT_INCREMENT) == 0 || strcmp(name, LISTENING_PORTS) == 0 ||
499
0
                strcmp(name, CALCULATE_CRC) == 0 || strcmp(name, CHECK_CRC) == 0 ||
500
0
                strcmp(name, ENABLE_TCP_NODELAY) == 0 || strcmp(name, TLS) == 0 ||
501
0
                strcmp(name, NON_BLOCKING_SEND) == 0  ||
502
0
                strcmp(name, SEGMENT_SIZE) == 0 || strcmp(name, PORT_QUEUE_CAPACITY) == 0 ||
503
0
                strcmp(name, PORT_OVERFLOW_POLICY) == 0 || strcmp(name, SEGMENT_OVERFLOW_POLICY) == 0 ||
504
0
                strcmp(name, HEALTHY_CHECK_TIMEOUT_MS) == 0 || strcmp(name, HEALTHY_CHECK_TIMEOUT_MS) == 0 ||
505
0
                strcmp(name, RTPS_DUMP_FILE) == 0)
506
0
        {
507
            // Parsed outside of this method
508
0
        }
509
0
        else
510
0
        {
511
0
            logError(XMLPARSER, "Invalid element found into 'rtpsTransportDescriptorType'. Name: " << name);
512
0
            return XMLP_ret::XML_ERROR;
513
0
        }
514
0
    }
515
0
    return XMLP_ret::XML_OK;
516
0
}
517
518
XMLP_ret XMLParser::parseXMLCommonTCPTransportData(
519
        tinyxml2::XMLElement* p_root,
520
        sp_transport_t p_transport)
521
0
{
522
    /*
523
        <xs:complexType name="rtpsTransportDescriptorType">
524
            <xs:all minOccurs="0">
525
                <xs:element name="keep_alive_frequency_ms" type="uint32Type"/>
526
                <xs:element name="keep_alive_timeout_ms" type="uint32Type"/>
527
                <xs:element name="max_logical_port" type="uint16Type"/>
528
                <xs:element name="logical_port_range" type="uint16Type"/>
529
                <xs:element name="logical_port_increment" type="uint16Type"/>
530
                <xs:element name="metadata_logical_port" type="uint16Type"/>
531
                <xs:element name="listening_ports" type="uint16ListType"/>
532
                <xs:sequence>
533
                    <xs:element name="port" type="uint16Type"/>
534
                </xs:sequence>
535
                <xs:element name="calculate_crc" type="boolType" minOccurs="0" maxOccurs="1"/>
536
                <xs:element name="check_crc" type="boolType" minOccurs="0" maxOccurs="1"/>
537
                <xs:element name="enable_tcp_nodelay" type="boolType" minOccurs="0" maxOccurs="1"/>
538
                <xs:element name="tls" type="tlsConfigType" minOccurs="0" maxOccurs="1"/>
539
            </xs:all>
540
        </xs:complexType>
541
     */
542
543
0
    XMLP_ret ret = XMLP_ret::XML_OK;
544
0
    std::shared_ptr<rtps::TCPTransportDescriptor> pTCPDesc =
545
0
            std::dynamic_pointer_cast<rtps::TCPTransportDescriptor>(p_transport);
546
0
    if (pTCPDesc != nullptr)
547
0
    {
548
0
        tinyxml2::XMLElement* p_aux0 = nullptr;
549
0
        const char* name = nullptr;
550
0
        for (p_aux0 = p_root->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
551
0
        {
552
0
            name = p_aux0->Name();
553
0
            if (strcmp(name, KEEP_ALIVE_FREQUENCY) == 0)
554
0
            {
555
                // keep_alive_frequency_ms - uint32Type
556
0
                int iFrequency(0);
557
0
                if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iFrequency, 0))
558
0
                {
559
0
                    return XMLP_ret::XML_ERROR;
560
0
                }
561
0
                pTCPDesc->keep_alive_frequency_ms = static_cast<uint32_t>(iFrequency);
562
0
            }
563
0
            else if (strcmp(name, KEEP_ALIVE_TIMEOUT) == 0)
564
0
            {
565
                // keep_alive_timeout_ms - uint32Type
566
0
                int iTimeout(0);
567
0
                if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iTimeout, 0))
568
0
                {
569
0
                    return XMLP_ret::XML_ERROR;
570
0
                }
571
0
                pTCPDesc->keep_alive_timeout_ms = static_cast<uint32_t>(iTimeout);
572
0
            }
573
0
            else if (strcmp(name, MAX_LOGICAL_PORT) == 0)
574
0
            {
575
                // max_logical_port - uint16Type
576
0
                int iPort(0);
577
0
                if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iPort, 0) || iPort < 0 || iPort > 65535)
578
0
                {
579
0
                    return XMLP_ret::XML_ERROR;
580
0
                }
581
0
                pTCPDesc->max_logical_port = static_cast<uint16_t>(iPort);
582
0
            }
583
0
            else if (strcmp(name, LOGICAL_PORT_RANGE) == 0)
584
0
            {
585
                // logical_port_range - uint16Type
586
0
                int iPort(0);
587
0
                if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iPort, 0) || iPort < 0 || iPort > 65535)
588
0
                {
589
0
                    return XMLP_ret::XML_ERROR;
590
0
                }
591
0
                pTCPDesc->logical_port_range = static_cast<uint16_t>(iPort);
592
0
            }
593
0
            else if (strcmp(name, LOGICAL_PORT_INCREMENT) == 0)
594
0
            {
595
                // logical_port_increment - uint16Type
596
0
                int iPort(0);
597
0
                if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iPort, 0) || iPort < 0 || iPort > 65535)
598
0
                {
599
0
                    return XMLP_ret::XML_ERROR;
600
0
                }
601
0
                pTCPDesc->logical_port_increment = static_cast<uint16_t>(iPort);
602
0
            }
603
            // enable_tcp_nodelay - boolType
604
0
            else if (strcmp(name, ENABLE_TCP_NODELAY) == 0)
605
0
            {
606
0
                if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &pTCPDesc->enable_tcp_nodelay, 0))
607
0
                {
608
0
                    return XMLP_ret::XML_ERROR;
609
0
                }
610
0
            }
611
0
            else if (strcmp(name, LISTENING_PORTS) == 0)
612
0
            {
613
                // listening_ports uint16ListType
614
0
                tinyxml2::XMLElement* p_aux1 = p_aux0->FirstChildElement(PORT);
615
0
                while (nullptr != p_aux1)
616
0
                {
617
0
                    int iPort = 0;
618
0
                    if (XMLP_ret::XML_OK != getXMLInt(p_aux1, &iPort, 0) || iPort < 0 || iPort > 65535)
619
0
                    {
620
0
                        return XMLP_ret::XML_ERROR;
621
0
                    }
622
623
0
                    pTCPDesc->add_listener_port(static_cast<uint16_t>(iPort));
624
0
                    p_aux1 = p_aux1->NextSiblingElement(PORT);
625
0
                }
626
0
            }
627
0
            else if (strcmp(name, CALCULATE_CRC) == 0)
628
0
            {
629
0
                if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &pTCPDesc->calculate_crc, 0))
630
0
                {
631
0
                    return XMLP_ret::XML_ERROR;
632
0
                }
633
0
            }
634
0
            else if (strcmp(name, CHECK_CRC) == 0)
635
0
            {
636
0
                if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &pTCPDesc->check_crc, 0))
637
0
                {
638
0
                    return XMLP_ret::XML_ERROR;
639
0
                }
640
0
            }
641
0
            else if (strcmp(name, TLS) == 0)
642
0
            {
643
0
                if (XMLP_ret::XML_OK != parse_tls_config(p_aux0, p_transport))
644
0
                {
645
0
                    return XMLP_ret::XML_ERROR;
646
0
                }
647
0
            }
648
0
            else if (strcmp(name, TCP_WAN_ADDR) == 0 || strcmp(name, TRANSPORT_ID) == 0 ||
649
0
                    strcmp(name, TYPE) == 0 || strcmp(name, SEND_BUFFER_SIZE) == 0 ||
650
0
                    strcmp(name, RECEIVE_BUFFER_SIZE) == 0 || strcmp(name, TTL) == 0 ||
651
0
                    strcmp(name, MAX_MESSAGE_SIZE) == 0 || strcmp(name, MAX_INITIAL_PEERS_RANGE) == 0 ||
652
0
                    strcmp(name, WHITE_LIST) == 0)
653
0
            {
654
                // Parsed Outside of this method
655
0
            }
656
0
            else
657
0
            {
658
0
                logError(XMLPARSER, "Invalid element found into 'rtpsTransportDescriptorType'. Name: " << name);
659
0
                return XMLP_ret::XML_ERROR;
660
0
            }
661
0
        }
662
0
    }
663
0
    else
664
0
    {
665
0
        logError(XMLPARSER, "Error parsing TCP Transport data");
666
0
        ret = XMLP_ret::XML_ERROR;
667
0
    }
668
669
0
    return ret;
670
0
}
671
672
XMLP_ret XMLParser::parseXMLCommonSharedMemTransportData(
673
        tinyxml2::XMLElement* p_root,
674
        sp_transport_t p_transport)
675
0
{
676
    /*
677
        <xs:complexType name="rtpsTransportDescriptorType">
678
            <xs:all minOccurs="0">
679
                <xs:element name="maxMessageSize" type="uint32Type" minOccurs="0" maxOccurs="1"/>
680
                <xs:element name="maxInitialPeersRange" type="uint32Type" minOccurs="0" maxOccurs="1"/>
681
                <xs:element name="segment_size" type="uint32Type" minOccurs="0" maxOccurs="1"/>
682
                <xs:element name="port_queue_capacity" type="uint32Type" minOccurs="0" maxOccurs="1"/>
683
                <xs:element name="healthy_check_timeout_ms" type="uint32Type" minOccurs="0" maxOccurs="1"/>
684
                <xs:element name="rtps_dump_file" type="stringType" minOccurs="0" maxOccurs="1"/>
685
                </xs:all>
686
        </xs:complexType>
687
     */
688
689
0
    XMLP_ret ret = XMLP_ret::XML_OK;
690
0
    std::shared_ptr<fastdds::rtps::SharedMemTransportDescriptor> transport_descriptor =
691
0
            std::dynamic_pointer_cast<fastdds::rtps::SharedMemTransportDescriptor>(p_transport);
692
0
    if (transport_descriptor != nullptr)
693
0
    {
694
0
        tinyxml2::XMLElement* p_aux0 = nullptr;
695
0
        const char* name = nullptr;
696
0
        for (p_aux0 = p_root->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
697
0
        {
698
0
            uint32_t aux;
699
0
            name = p_aux0->Name();
700
0
            if (strcmp(name, SEGMENT_SIZE) == 0)
701
0
            {
702
0
                if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &aux, 0))
703
0
                {
704
0
                    return XMLP_ret::XML_ERROR;
705
0
                }
706
0
                transport_descriptor->segment_size(static_cast<uint32_t>(aux));
707
0
            }
708
0
            else if (strcmp(name, PORT_QUEUE_CAPACITY) == 0)
709
0
            {
710
0
                if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &aux, 0))
711
0
                {
712
0
                    return XMLP_ret::XML_ERROR;
713
0
                }
714
0
                transport_descriptor->port_queue_capacity(static_cast<uint32_t>(aux));
715
0
            }
716
0
            else if (strcmp(name, HEALTHY_CHECK_TIMEOUT_MS) == 0)
717
0
            {
718
0
                if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &aux, 0))
719
0
                {
720
0
                    return XMLP_ret::XML_ERROR;
721
0
                }
722
0
                transport_descriptor->healthy_check_timeout_ms(static_cast<uint32_t>(aux));
723
0
            }
724
0
            else if (strcmp(name, RTPS_DUMP_FILE) == 0)
725
0
            {
726
0
                std::string str;
727
0
                if (XMLP_ret::XML_OK != getXMLString(p_aux0, &str, 0))
728
0
                {
729
0
                    return XMLP_ret::XML_ERROR;
730
0
                }
731
0
                transport_descriptor->rtps_dump_file(str);
732
0
            }
733
0
            else if (strcmp(name, MAX_MESSAGE_SIZE) == 0)
734
0
            {
735
                // maxMessageSize - uint32Type
736
0
                uint32_t uSize = 0;
737
0
                if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &uSize, 0))
738
0
                {
739
0
                    return XMLP_ret::XML_ERROR;
740
0
                }
741
0
                transport_descriptor->max_message_size(uSize);
742
0
            }
743
0
            else if (strcmp(name, MAX_INITIAL_PEERS_RANGE) == 0)
744
0
            {
745
                // maxInitialPeersRange - uint32Type
746
0
                uint32_t uRange = 0;
747
0
                if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &uRange, 0))
748
0
                {
749
0
                    return XMLP_ret::XML_ERROR;
750
0
                }
751
0
                transport_descriptor->maxInitialPeersRange = uRange;
752
0
            }
753
0
            else if (strcmp(name, TRANSPORT_ID) == 0 || strcmp(name, TYPE) == 0)
754
0
            {
755
                // Parsed Outside of this method
756
0
            }
757
0
            else
758
0
            {
759
0
                logError(XMLPARSER, "Invalid element found into 'rtpsTransportDescriptorType'. Name: " << name);
760
0
                return XMLP_ret::XML_ERROR;
761
0
            }
762
0
        }
763
0
    }
764
0
    else
765
0
    {
766
0
        logError(XMLPARSER, "Error parsing SharedMem Transport data");
767
0
        ret = XMLP_ret::XML_ERROR;
768
0
    }
769
770
0
    return ret;
771
0
}
772
773
XMLP_ret XMLParser::parse_tls_config(
774
        tinyxml2::XMLElement* p_root,
775
        sp_transport_t tcp_transport)
776
0
{
777
    /*
778
        XSD:
779
        <xs:simpleType name="tlsOptionsType">
780
            <xs:restriction base="xs:string">
781
                <xs:enumeration value="DEFAULT_WORKAROUNDS"/>
782
                <xs:enumeration value="NO_COMPRESSION"/>
783
                <xs:enumeration value="NO_SSLV2"/>
784
                <xs:enumeration value="NO_SSLV3"/>
785
                <xs:enumeration value="NO_TLSV1"/>
786
                <xs:enumeration value="NO_TLSV1_1"/>
787
                <xs:enumeration value="NO_TLSV1_2"/>
788
                <xs:enumeration value="NO_TLSV1_3"/>
789
                <xs:enumeration value="SINGLE_DH_USE"/>
790
            </xs:restriction>
791
        </xs:simpleType>
792
793
        <xs:complexType name="tlsOptionsVectorType">
794
            <xs:sequence>
795
                <xs:element name="option" type="tlsOptionsType" minOccurs="0" maxOccurs="unbounded"/>
796
            </xs:sequence>
797
        </xs:complexType>
798
799
        <xs:simpleType name="tlsVerifyModeType">
800
            <xs:restriction base="xs:string">
801
                <xs:enumeration value="VERIFY_NONE"/>
802
                <xs:enumeration value="VERIFY_PEER"/>
803
                <xs:enumeration value="VERIFY_FAIL_IF_NO_PEER_CERT"/>
804
                <xs:enumeration value="VERIFY_CLIENT_ONCE"/>
805
            </xs:restriction>
806
        </xs:simpleType>
807
808
        <xs:complexType name="tlsVerifyModeVectorType">
809
            <xs:sequence>
810
                <xs:element name="verify" type="tlsVerifyModeType" minOccurs="0" maxOccurs="unbounded"/>
811
            </xs:sequence>
812
        </xs:complexType>
813
814
        <xs:complexType name="tlsConfigType">
815
            <xs:all minOccurs="0">
816
                <xs:element name="password" type="stringType" minOccurs="0" maxOccurs="1"/>
817
                <xs:element name="options" type="tlsOptionsVectorType" minOccurs="0" maxOccurs="1"/>
818
                <xs:element name="cert_chain_file" type="stringType" minOccurs="0" maxOccurs="1"/>
819
                <xs:element name="private_key_file" type="stringType" minOccurs="0" maxOccurs="1"/>
820
                <xs:element name="tmp_dh_file" type="stringType" minOccurs="0" maxOccurs="1"/>
821
                <xs:element name="verify_file" type="stringType" minOccurs="0" maxOccurs="1"/>
822
                <xs:element name="verify_mode" type="tlsVerifyModeVectorType" minOccurs="0" maxOccurs="1"/>
823
                <xs:element name="verify_paths" type="tlsVerifyPathVectorType" minOccurs="0" maxOccurs="1"/>
824
                <xs:element name="default_verify_path" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
825
                <xs:element name="verify_depth" type="xs:int" minOccurs="0" maxOccurs="1"/>
826
                <xs:element name="rsa_private_key_file" type="stringType" minOccurs="0" maxOccurs="1"/>
827
            </xs:all>
828
        </xs:complexType>
829
830
        XML Example:
831
        <tls>
832
            <password>Contraseña</password>
833
            <private_key_file>Key_file.pem</private_key_file>
834
            <cert_chain_file>Chain.pem</cert_chain_file>
835
            <tmp_dh_file>DH.pem</tmp_dh_file>
836
            <verify_file>verify.pem</verify_file>
837
            <verify_mode>
838
                <verify>VERIFY_PEER</verify>
839
            </verify_mode>
840
            <options>
841
                <option>NO_TLSV1</option>
842
                <option>NO_TLSV1_1</option>
843
            </options>
844
        </tls>
845
     */
846
0
    using namespace rtps;
847
0
    using TCPDescriptor = std::shared_ptr<rtps::TCPTransportDescriptor>;
848
0
    using TLSVerifyMode = TCPTransportDescriptor::TLSConfig::TLSVerifyMode;
849
0
    using TLSOption = TCPTransportDescriptor::TLSConfig::TLSOptions;
850
0
    using TLSHandShakeMode = TCPTransportDescriptor::TLSConfig::TLSHandShakeRole;
851
852
0
    XMLP_ret ret = XMLP_ret::XML_OK;
853
854
0
    TCPDescriptor pTCPDesc = std::dynamic_pointer_cast<rtps::TCPTransportDescriptor>(tcp_transport);
855
0
    pTCPDesc->apply_security = true;
856
857
0
    tinyxml2::XMLElement* p_aux0 = nullptr;
858
859
0
    for (p_aux0 = p_root->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
860
0
    {
861
0
        const std::string config = p_aux0->Value();
862
0
        if (config.compare(TLS_PASSWORD) == 0)
863
0
        {
864
0
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &pTCPDesc->tls_config.password, 0))
865
0
            {
866
0
                ret = XMLP_ret::XML_ERROR;
867
0
            }
868
0
        }
869
0
        else if (config.compare(TLS_PRIVATE_KEY_FILE) == 0)
870
0
        {
871
0
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &pTCPDesc->tls_config.private_key_file, 0))
872
0
            {
873
0
                ret = XMLP_ret::XML_ERROR;
874
0
            }
875
0
        }
876
0
        else if (config.compare(TLS_CERT_CHAIN_FILE) == 0)
877
0
        {
878
0
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &pTCPDesc->tls_config.cert_chain_file, 0))
879
0
            {
880
0
                ret = XMLP_ret::XML_ERROR;
881
0
            }
882
0
        }
883
0
        else if (config.compare(TLS_TMP_DH_FILE) == 0)
884
0
        {
885
0
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &pTCPDesc->tls_config.tmp_dh_file, 0))
886
0
            {
887
0
                ret = XMLP_ret::XML_ERROR;
888
0
            }
889
0
        }
890
0
        else if (config.compare(TLS_VERIFY_FILE) == 0)
891
0
        {
892
0
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &pTCPDesc->tls_config.verify_file, 0))
893
0
            {
894
0
                ret = XMLP_ret::XML_ERROR;
895
0
            }
896
0
        }
897
0
        else if (config.compare(TLS_VERIFY_PATHS) == 0)
898
0
        {
899
0
            tinyxml2::XMLElement* p_path = p_aux0->FirstChildElement();
900
901
0
            while (p_path != nullptr)
902
0
            {
903
0
                std::string type = p_path->Value();
904
0
                if (type.compare(TLS_VERIFY_PATH) == 0)
905
0
                {
906
0
                    std::string path;
907
908
0
                    if (XMLP_ret::XML_OK != getXMLString(p_path, &path, 0))
909
0
                    {
910
0
                        ret = XMLP_ret::XML_ERROR;
911
0
                    }
912
0
                    else
913
0
                    {
914
0
                        pTCPDesc->tls_config.verify_paths.push_back(path);
915
0
                    }
916
917
0
                    if (ret == XMLP_ret::XML_ERROR)
918
0
                    {
919
                        // Break while loop
920
0
                        break;
921
0
                    }
922
0
                    p_path = p_path->NextSiblingElement();
923
0
                }
924
0
                else
925
0
                {
926
0
                    logError(XMLPARSER, "Unrecognized verify paths label: " << p_path->Value());
927
0
                    ret = XMLP_ret::XML_ERROR;
928
0
                    break;
929
0
                }
930
0
            }
931
0
        }
932
0
        else if (config.compare(TLS_VERIFY_DEPTH) == 0)
933
0
        {
934
0
            if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &pTCPDesc->tls_config.verify_depth, 0))
935
0
            {
936
0
                ret = XMLP_ret::XML_ERROR;
937
0
            }
938
0
        }
939
0
        else if (config.compare(TLS_DEFAULT_VERIFY_PATH) == 0)
940
0
        {
941
0
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &pTCPDesc->tls_config.default_verify_path, 0))
942
0
            {
943
0
                ret = XMLP_ret::XML_ERROR;
944
0
            }
945
0
        }
946
0
        else if (config.compare(TLS_RSA_PRIVATE_KEY_FILE) == 0)
947
0
        {
948
0
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &pTCPDesc->tls_config.rsa_private_key_file, 0))
949
0
            {
950
0
                ret = XMLP_ret::XML_ERROR;
951
0
            }
952
0
        }
953
0
        else if (config.compare(TLS_HANDSHAKE_ROLE) == 0)
954
0
        {
955
0
            std::string handshake_mode;
956
0
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &handshake_mode, 0))
957
0
            {
958
0
                ret = XMLP_ret::XML_ERROR;
959
0
            }
960
0
            else
961
0
            {
962
0
                if (handshake_mode.compare(TLS_HANDSHAKE_ROLE_DEFAULT) == 0)
963
0
                {
964
0
                    pTCPDesc->tls_config.handshake_role = TLSHandShakeMode::DEFAULT;
965
0
                }
966
0
                else if (handshake_mode.compare(TLS_HANDSHAKE_ROLE_SERVER) == 0)
967
0
                {
968
0
                    pTCPDesc->tls_config.handshake_role = TLSHandShakeMode::SERVER;
969
0
                }
970
0
                else if (handshake_mode.compare(TLS_HANDSHAKE_ROLE_CLIENT) == 0)
971
0
                {
972
0
                    pTCPDesc->tls_config.handshake_role = TLSHandShakeMode::CLIENT;
973
0
                }
974
0
                else
975
0
                {
976
0
                    logError(XMLPARSER, "Error parsing TLS configuration handshake_mode unrecognized "
977
0
                            << handshake_mode << ".");
978
0
                    ret = XMLP_ret::XML_ERROR;
979
0
                }
980
0
            }
981
0
        }
982
0
        else if (config.compare(TLS_VERIFY_MODE) == 0)
983
0
        {
984
0
            tinyxml2::XMLElement* p_verify = p_aux0->FirstChildElement();
985
0
            while (p_verify != nullptr)
986
0
            {
987
0
                std::string type = p_verify->Value();
988
0
                if (type.compare(TLS_VERIFY) == 0)
989
0
                {
990
0
                    std::string verify_mode;
991
992
0
                    if (XMLP_ret::XML_OK != getXMLString(p_verify, &verify_mode, 0))
993
0
                    {
994
0
                        ret = XMLP_ret::XML_ERROR;
995
0
                    }
996
0
                    else
997
0
                    {
998
0
                        if (verify_mode.compare(TLS_VERIFY_NONE) == 0)
999
0
                        {
1000
0
                            pTCPDesc->tls_config.add_verify_mode(TLSVerifyMode::VERIFY_NONE);
1001
0
                        }
1002
0
                        else if (verify_mode.compare(TLS_VERIFY_PEER) == 0)
1003
0
                        {
1004
0
                            pTCPDesc->tls_config.add_verify_mode(TLSVerifyMode::VERIFY_PEER);
1005
0
                        }
1006
0
                        else if (verify_mode.compare(TLS_VERIFY_FAIL_IF_NO_PEER_CERT) == 0)
1007
0
                        {
1008
0
                            pTCPDesc->tls_config.add_verify_mode(TLSVerifyMode::VERIFY_FAIL_IF_NO_PEER_CERT);
1009
0
                        }
1010
0
                        else if (verify_mode.compare(TLS_VERIFY_CLIENT_ONCE) == 0)
1011
0
                        {
1012
0
                            pTCPDesc->tls_config.add_verify_mode(TLSVerifyMode::VERIFY_CLIENT_ONCE);
1013
0
                        }
1014
0
                        else
1015
0
                        {
1016
0
                            logError(XMLPARSER, "Error parsing TLS configuration verify_mode unrecognized "
1017
0
                                    << verify_mode << ".");
1018
0
                            ret = XMLP_ret::XML_ERROR;
1019
0
                        }
1020
0
                    }
1021
0
                }
1022
0
                else
1023
0
                {
1024
0
                    logError(XMLPARSER, "Error parsing TLS configuration found unrecognized node "
1025
0
                            << type << ".");
1026
0
                    ret = XMLP_ret::XML_ERROR;
1027
0
                }
1028
1029
0
                if (ret == XMLP_ret::XML_ERROR)
1030
0
                {
1031
                    // Break while loop
1032
0
                    break;
1033
0
                }
1034
1035
0
                p_verify = p_verify->NextSiblingElement();
1036
0
            }
1037
0
        }
1038
0
        else if (config.compare(TLS_OPTIONS) == 0)
1039
0
        {
1040
0
            tinyxml2::XMLElement* p_option = p_aux0->FirstChildElement();
1041
0
            while (p_option != nullptr)
1042
0
            {
1043
0
                std::string type = p_option->Value();
1044
0
                if (type.compare(TLS_OPTION) == 0)
1045
0
                {
1046
0
                    std::string option;
1047
1048
0
                    if (XMLP_ret::XML_OK != getXMLString(p_option, &option, 0))
1049
0
                    {
1050
0
                        ret = XMLP_ret::XML_ERROR;
1051
0
                    }
1052
0
                    else
1053
0
                    {
1054
0
                        if (option.compare(TLS_DEFAULT_WORKAROUNDS) == 0)
1055
0
                        {
1056
0
                            pTCPDesc->tls_config.add_option(TLSOption::DEFAULT_WORKAROUNDS);
1057
0
                        }
1058
0
                        else if (option.compare(TLS_NO_COMPRESSION) == 0)
1059
0
                        {
1060
0
                            pTCPDesc->tls_config.add_option(TLSOption::NO_COMPRESSION);
1061
0
                        }
1062
0
                        else if (option.compare(TLS_NO_SSLV2) == 0)
1063
0
                        {
1064
0
                            pTCPDesc->tls_config.add_option(TLSOption::NO_SSLV2);
1065
0
                        }
1066
0
                        else if (option.compare(TLS_NO_SSLV3) == 0)
1067
0
                        {
1068
0
                            pTCPDesc->tls_config.add_option(TLSOption::NO_SSLV3);
1069
0
                        }
1070
0
                        else if (option.compare(TLS_NO_TLSV1) == 0)
1071
0
                        {
1072
0
                            pTCPDesc->tls_config.add_option(TLSOption::NO_TLSV1);
1073
0
                        }
1074
0
                        else if (option.compare(TLS_NO_TLSV1_1) == 0)
1075
0
                        {
1076
0
                            pTCPDesc->tls_config.add_option(TLSOption::NO_TLSV1_1);
1077
0
                        }
1078
0
                        else if (option.compare(TLS_NO_TLSV1_2) == 0)
1079
0
                        {
1080
0
                            pTCPDesc->tls_config.add_option(TLSOption::NO_TLSV1_2);
1081
0
                        }
1082
0
                        else if (option.compare(TLS_NO_TLSV1_3) == 0)
1083
0
                        {
1084
0
                            pTCPDesc->tls_config.add_option(TLSOption::NO_TLSV1_3);
1085
0
                        }
1086
0
                        else if (option.compare(TLS_SINGLE_DH_USE) == 0)
1087
0
                        {
1088
0
                            pTCPDesc->tls_config.add_option(TLSOption::SINGLE_DH_USE);
1089
0
                        }
1090
0
                        else
1091
0
                        {
1092
0
                            logError(XMLPARSER, "Error parsing TLS configuration option unrecognized "
1093
0
                                    << option << ".");
1094
0
                            ret = XMLP_ret::XML_ERROR;
1095
0
                        }
1096
0
                    }
1097
0
                }
1098
0
                else
1099
0
                {
1100
0
                    logError(XMLPARSER, "Error parsing TLS options found unrecognized node "
1101
0
                            << type << ".");
1102
0
                    ret = XMLP_ret::XML_ERROR;
1103
0
                }
1104
1105
1106
0
                if (ret == XMLP_ret::XML_ERROR)
1107
0
                {
1108
                    // Break while loop
1109
0
                    break;
1110
0
                }
1111
1112
0
                p_option = p_option->NextSiblingElement();
1113
0
            }
1114
0
        }
1115
0
        else
1116
0
        {
1117
0
            logError(XMLPARSER, "Error parsing TLS configuration: Field " << config << " not recognized.");
1118
0
            ret = XMLP_ret::XML_ERROR;
1119
0
        }
1120
1121
        // Stop parsing on error
1122
0
        if (ret == XMLP_ret::XML_ERROR)
1123
0
        {
1124
0
            logError(XMLPARSER, "Error parsing TLS configuration's field '" << config << "'.");
1125
0
            break;
1126
0
        }
1127
0
    }
1128
1129
0
    return ret;
1130
0
}
1131
1132
XMLP_ret XMLParser::parseXMLLibrarySettings(
1133
        tinyxml2::XMLElement* p_root)
1134
197
{
1135
    /*
1136
        <xs:complexType name="LibrarySettingsType">
1137
            <xs:all minOccurs="0">
1138
                <xs:element name="intraprocess_delivery" type="IntraprocessDeliveryType"/>
1139
            </xs:all>
1140
        </xs:complexType>
1141
     */
1142
1143
197
    XMLP_ret ret = XMLP_ret::XML_OK;
1144
197
    std::string sId = "";
1145
1146
197
    uint8_t ident = 1;
1147
197
    tinyxml2::XMLElement* p_aux0 = nullptr;
1148
197
    p_aux0 = p_root->FirstChildElement(INTRAPROCESS_DELIVERY);
1149
197
    if (nullptr == p_aux0)
1150
197
    {
1151
197
        logError(XMLPARSER, "Not found '" << INTRAPROCESS_DELIVERY << "' attribute");
1152
197
        return XMLP_ret::XML_ERROR;
1153
197
    }
1154
0
    else
1155
0
    {
1156
0
        LibrarySettingsAttributes library_settings;
1157
0
        if (XMLP_ret::XML_OK != getXMLEnum(p_aux0, &library_settings.intraprocess_delivery, ident))
1158
0
        {
1159
0
            return XMLP_ret::XML_ERROR;
1160
0
        }
1161
1162
0
        XMLProfileManager::library_settings(library_settings);
1163
0
    }
1164
1165
0
    return ret;
1166
197
}
1167
1168
XMLP_ret XMLParser::parseXMLParticipantProf(
1169
        tinyxml2::XMLElement* p_root,
1170
        BaseNode& rootNode)
1171
19.6k
{
1172
19.6k
    XMLP_ret ret = XMLP_ret::XML_OK;
1173
19.6k
    up_participant_t participant_atts{new ParticipantAttributes};
1174
19.6k
    up_node_participant_t participant_node{new node_participant_t{NodeType::PARTICIPANT, std::move(participant_atts)}};
1175
19.6k
    if (XMLP_ret::XML_OK == fillDataNode(p_root, *participant_node))
1176
4.27k
    {
1177
4.27k
        rootNode.addChild(std::move(participant_node));
1178
4.27k
    }
1179
15.3k
    else
1180
15.3k
    {
1181
15.3k
        logError(XMLPARSER, "Error parsing participant profile");
1182
15.3k
        ret = XMLP_ret::XML_ERROR;
1183
15.3k
    }
1184
1185
19.6k
    return ret;
1186
19.6k
}
1187
1188
XMLP_ret XMLParser::parseXMLPublisherProf(
1189
        tinyxml2::XMLElement* p_root,
1190
        BaseNode& rootNode)
1191
19.1k
{
1192
19.1k
    XMLP_ret ret = XMLP_ret::XML_OK;
1193
19.1k
    up_publisher_t publisher_atts{new PublisherAttributes};
1194
19.1k
    up_node_publisher_t publisher_node{new node_publisher_t{NodeType::PUBLISHER, std::move(publisher_atts)}};
1195
19.1k
    if (XMLP_ret::XML_OK == fillDataNode(p_root, *publisher_node))
1196
7.64k
    {
1197
7.64k
        rootNode.addChild(std::move(publisher_node));
1198
7.64k
    }
1199
11.4k
    else
1200
11.4k
    {
1201
11.4k
        logError(XMLPARSER, "Error parsing publisher profile");
1202
11.4k
        ret = XMLP_ret::XML_ERROR;
1203
11.4k
    }
1204
19.1k
    return ret;
1205
19.1k
}
1206
1207
XMLP_ret XMLParser::parseXMLSubscriberProf(
1208
        tinyxml2::XMLElement* p_root,
1209
        BaseNode& rootNode)
1210
15.0k
{
1211
15.0k
    XMLP_ret ret = XMLP_ret::XML_OK;
1212
15.0k
    up_subscriber_t subscriber_atts{new SubscriberAttributes};
1213
15.0k
    up_node_subscriber_t subscriber_node{new node_subscriber_t{NodeType::SUBSCRIBER, std::move(subscriber_atts)}};
1214
15.0k
    if (XMLP_ret::XML_OK == fillDataNode(p_root, *subscriber_node))
1215
6.58k
    {
1216
6.58k
        rootNode.addChild(std::move(subscriber_node));
1217
6.58k
    }
1218
8.51k
    else
1219
8.51k
    {
1220
8.51k
        logError(XMLPARSER, "Error parsing subscriber profile");
1221
8.51k
        ret = XMLP_ret::XML_ERROR;
1222
8.51k
    }
1223
15.0k
    return ret;
1224
15.0k
}
1225
1226
XMLP_ret XMLParser::parseXMLTopicData(
1227
        tinyxml2::XMLElement* p_root,
1228
        BaseNode& rootNode)
1229
13.6k
{
1230
13.6k
    XMLP_ret ret = XMLP_ret::XML_OK;
1231
13.6k
    up_topic_t topic_atts{new TopicAttributes};
1232
13.6k
    up_node_topic_t topic_node{new node_topic_t{NodeType::TOPIC, std::move(topic_atts)}};
1233
13.6k
    if (XMLP_ret::XML_OK == fillDataNode(p_root, *topic_node))
1234
10.7k
    {
1235
10.7k
        rootNode.addChild(std::move(topic_node));
1236
10.7k
    }
1237
2.92k
    else
1238
2.92k
    {
1239
2.92k
        logError(XMLPARSER, "Error parsing topic data node");
1240
2.92k
        ret = XMLP_ret::XML_ERROR;
1241
2.92k
    }
1242
13.6k
    return ret;
1243
13.6k
}
1244
1245
XMLP_ret XMLParser::parseXMLRequesterProf(
1246
        tinyxml2::XMLElement* p_root,
1247
        BaseNode& rootNode)
1248
12.1k
{
1249
12.1k
    XMLP_ret ret = XMLP_ret::XML_OK;
1250
12.1k
    up_requester_t requester_atts{new RequesterAttributes};
1251
12.1k
    up_node_requester_t requester_node{new node_requester_t{NodeType::REQUESTER, std::move(requester_atts)}};
1252
12.1k
    if (XMLP_ret::XML_OK == fillDataNode(p_root, *requester_node))
1253
5.80k
    {
1254
5.80k
        rootNode.addChild(std::move(requester_node));
1255
5.80k
    }
1256
6.31k
    else
1257
6.31k
    {
1258
6.31k
        logError(XMLPARSER, "Error parsing requester profile");
1259
6.31k
        ret = XMLP_ret::XML_ERROR;
1260
6.31k
    }
1261
12.1k
    return ret;
1262
12.1k
}
1263
1264
XMLP_ret XMLParser::parseXMLReplierProf(
1265
        tinyxml2::XMLElement* p_root,
1266
        BaseNode& rootNode)
1267
12.7k
{
1268
12.7k
    XMLP_ret ret = XMLP_ret::XML_OK;
1269
12.7k
    up_replier_t replier_atts{new ReplierAttributes};
1270
12.7k
    up_node_replier_t replier_node{new node_replier_t{NodeType::REPLIER, std::move(replier_atts)}};
1271
12.7k
    if (XMLP_ret::XML_OK == fillDataNode(p_root, *replier_node))
1272
5.92k
    {
1273
5.92k
        rootNode.addChild(std::move(replier_node));
1274
5.92k
    }
1275
6.86k
    else
1276
6.86k
    {
1277
6.86k
        logError(XMLPARSER, "Error parsing replier profile");
1278
6.86k
        ret = XMLP_ret::XML_ERROR;
1279
6.86k
    }
1280
12.7k
    return ret;
1281
12.7k
}
1282
1283
XMLP_ret XMLParser::parseProfiles(
1284
        tinyxml2::XMLElement* p_root,
1285
        BaseNode& profilesNode)
1286
9.96k
{
1287
    /*
1288
        <xs:element name="profiles">
1289
            <xs:complexType>
1290
                <xs:sequence>
1291
                    <xs:element name="library_settings" type="LibrarySettingsType" minOccurs="0" maxOccurs="unbounded"/>
1292
                    <xs:element name="transport_descriptors" type="TransportDescriptorListType" minOccurs="0" maxOccurs="unbounded"/>
1293
                    <xs:element name="participant" type="participantProfileType" minOccurs="0" maxOccurs="unbounded"/>
1294
                    <xs:element name="publisher" type="publisherProfileType" minOccurs="0" maxOccurs="unbounded"/>
1295
                    <xs:element name="subscriber" type="subscriberProfileType" minOccurs="0" maxOccurs="unbounded"/>
1296
                    <xs:element name="topic" type="topicAttributesType" minOccurs="0" maxOccurs="unbounded"/>
1297
                </xs:sequence>
1298
            </xs:complexType>
1299
        </xs:element>
1300
     */
1301
1302
9.96k
    tinyxml2::XMLElement* p_profile = p_root->FirstChildElement();
1303
9.96k
    const char* tag = nullptr;
1304
9.96k
    bool parseOk = true;
1305
9.96k
    XMLP_ret ret = XMLP_ret::XML_OK;
1306
583k
    while (nullptr != p_profile)
1307
573k
    {
1308
573k
        if (nullptr != (tag = p_profile->Value()))
1309
573k
        {
1310
            // If profile parsing functions fails, log and continue.
1311
573k
            if (strcmp(tag, TRANSPORT_DESCRIPTORS) == 0)
1312
360
            {
1313
360
                parseOk &= parseXMLTransportsProf(p_profile) == XMLP_ret::XML_OK;
1314
360
            }
1315
573k
            else if (strcmp(tag, LIBRARY_SETTINGS) == 0)
1316
195
            {
1317
195
                parseOk &= parseXMLLibrarySettings(p_profile) == XMLP_ret::XML_OK;
1318
195
            }
1319
573k
            else if (strcmp(tag, PARTICIPANT) == 0)
1320
18.9k
            {
1321
18.9k
                parseOk &= parseXMLParticipantProf(p_profile, profilesNode) == XMLP_ret::XML_OK;
1322
18.9k
            }
1323
554k
            else if (strcmp(tag, PUBLISHER) == 0 || strcmp(tag, DATA_WRITER) == 0)
1324
16.1k
            {
1325
16.1k
                parseOk &= parseXMLPublisherProf(p_profile, profilesNode) == XMLP_ret::XML_OK;
1326
16.1k
            }
1327
538k
            else if (strcmp(tag, SUBSCRIBER) == 0 || strcmp(tag, DATA_READER) == 0)
1328
11.8k
            {
1329
11.8k
                parseOk &= parseXMLSubscriberProf(p_profile, profilesNode) == XMLP_ret::XML_OK;
1330
11.8k
            }
1331
526k
            else if (strcmp(tag, TOPIC) == 0)
1332
12.1k
            {
1333
12.1k
                parseOk &= parseXMLTopicData(p_profile, profilesNode) == XMLP_ret::XML_OK;
1334
12.1k
            }
1335
514k
            else if (strcmp(tag, TYPES) == 0)
1336
16.4k
            {
1337
16.4k
                parseOk &= parseXMLTypes(p_profile) == XMLP_ret::XML_OK;
1338
16.4k
            }
1339
497k
            else if (strcmp(tag, REQUESTER) == 0)
1340
11.6k
            {
1341
11.6k
                parseOk &= parseXMLRequesterProf(p_profile, profilesNode) == XMLP_ret::XML_OK;
1342
11.6k
            }
1343
486k
            else if (strcmp(tag, REPLIER) == 0)
1344
12.2k
            {
1345
12.2k
                parseOk &= parseXMLReplierProf(p_profile, profilesNode) == XMLP_ret::XML_OK;
1346
12.2k
            }
1347
473k
            else if (strcmp(tag, QOS_PROFILE) == 0)
1348
328
            {
1349
328
                logError(XMLPARSER, "Field 'QOS_PROFILE' do not supported for now");
1350
328
            }
1351
473k
            else if (strcmp(tag, APPLICATION) == 0)
1352
266
            {
1353
266
                logError(XMLPARSER, "Field 'APPLICATION' do not supported for now");
1354
266
            }
1355
473k
            else if (strcmp(tag, TYPE) == 0)
1356
2.10k
            {
1357
2.10k
                logError(XMLPARSER, "Field 'TYPE' do not supported for now");
1358
2.10k
            }
1359
471k
            else
1360
471k
            {
1361
471k
                parseOk = false;
1362
471k
                logError(XMLPARSER, "Not expected tag: '" << tag << "'");
1363
471k
            }
1364
573k
        }
1365
1366
573k
        if (!parseOk)
1367
542k
        {
1368
542k
            logError(XMLPARSER, "Error parsing profile's tag " << tag);
1369
542k
            ret = XMLP_ret::XML_ERROR;
1370
542k
        }
1371
573k
        p_profile = p_profile->NextSiblingElement();
1372
573k
    }
1373
9.96k
    return ret;
1374
9.96k
}
1375
1376
XMLP_ret XMLParser::parseLogConfig(
1377
        tinyxml2::XMLElement* p_root)
1378
2.32k
{
1379
    /*
1380
       <xs:element name="log">
1381
       <xs:complexType>
1382
        <xs:boolean name="use_default"/>
1383
        <xs:sequence>
1384
          <xs:element maxOccurs="consumer">
1385
            <xs:complexType>
1386
              <xs:element name="class" type="string" minOccurs="1" maxOccurs="1"/>
1387
              <xs:sequence>
1388
                <xs:element name="propertyType"/>
1389
              </xs:sequence>
1390
            </xs:complexType>
1391
        </xs:sequence>
1392
       </xs:complexType>
1393
       </xs:element>
1394
     */
1395
1396
2.32k
    XMLP_ret ret = XMLP_ret::XML_OK;
1397
2.32k
    tinyxml2::XMLElement* p_aux0 = p_root->FirstChildElement(LOG);
1398
2.32k
    if (p_aux0 == nullptr)
1399
2.23k
    {
1400
2.23k
        p_aux0 = p_root;
1401
2.23k
    }
1402
1403
2.32k
    tinyxml2::XMLElement* p_element = p_aux0->FirstChildElement();
1404
2.32k
    const char* tag = nullptr;
1405
5.18k
    while (nullptr != p_element)
1406
2.85k
    {
1407
2.85k
        if (nullptr != (tag = p_element->Value()))
1408
2.85k
        {
1409
2.85k
            if (strcmp(tag, USE_DEFAULT) == 0)
1410
0
            {
1411
0
                bool use_default = true;
1412
0
                std::string auxBool = p_element->GetText();
1413
0
                if (std::strcmp(auxBool.c_str(), "FALSE") == 0)
1414
0
                {
1415
0
                    use_default = false;
1416
0
                }
1417
0
                if (!use_default)
1418
0
                {
1419
0
                    eprosima::fastdds::dds::Log::ClearConsumers();
1420
0
                }
1421
0
            }
1422
2.85k
            else if (strcmp(tag, CONSUMER) == 0)
1423
1.56k
            {
1424
1.56k
                ret = parseXMLConsumer(*p_element);
1425
1.56k
                if (ret == XMLP_ret::XML_ERROR)
1426
0
                {
1427
0
                    return ret;
1428
0
                }
1429
1.56k
            }
1430
1.29k
            else
1431
1.29k
            {
1432
1.29k
                logError(XMLPARSER, "Not expected tag: '" << tag << "'");
1433
1.29k
                ret = XMLP_ret::XML_ERROR;
1434
1.29k
            }
1435
2.85k
        }
1436
2.85k
        p_element = p_element->NextSiblingElement(CONSUMER);
1437
2.85k
    }
1438
2.32k
    return ret;
1439
2.32k
}
1440
1441
XMLP_ret XMLParser::parseXMLConsumer(
1442
        tinyxml2::XMLElement& consumer)
1443
1.56k
{
1444
1.56k
    using namespace eprosima::fastdds::dds;
1445
1446
1.56k
    XMLP_ret ret = XMLP_ret::XML_OK;
1447
1.56k
    tinyxml2::XMLElement* p_element = consumer.FirstChildElement(CLASS);
1448
1449
1.56k
    if (p_element != nullptr)
1450
0
    {
1451
0
        std::string classStr = p_element->GetText();
1452
1453
0
        if (std::strcmp(classStr.c_str(), "StdoutConsumer") == 0)
1454
0
        {
1455
0
            Log::RegisterConsumer(std::unique_ptr<LogConsumer>(new StdoutConsumer));
1456
0
        }
1457
0
        else if (std::strcmp(classStr.c_str(), "StdoutErrConsumer") == 0)
1458
0
        {
1459
            /* Register a StdoutErrConsumer */
1460
1461
            // Get first property
1462
0
            tinyxml2::XMLElement* property = consumer.FirstChildElement(PROPERTY);
1463
0
            if (nullptr == property)
1464
0
            {
1465
                // If no properties are specified, create the consumer with default values
1466
0
                Log::RegisterConsumer(std::unique_ptr<LogConsumer>(new StdoutErrConsumer));
1467
0
            }
1468
0
            else
1469
0
            {
1470
                // Only one property is supported. Its name is `stderr_threshold`, and its value is a log kind specified
1471
                // as a string in the form `Log::Kind::<Kind>`.
1472
0
                tinyxml2::XMLElement* p_auxName = nullptr;    // Property name
1473
0
                tinyxml2::XMLElement* p_auxValue = nullptr;   // Property value
1474
0
                uint8_t stderr_threshold_property_count = 0;  // Occurrences count. Only one is allowed
1475
1476
                // Get default threshold
1477
0
                Log::Kind threshold = StdoutErrConsumer::STDERR_THRESHOLD_DEFAULT;
1478
1479
                // Iterate over the properties
1480
0
                while (nullptr != property)
1481
0
                {
1482
0
                    if (nullptr != (p_auxName = property->FirstChildElement(NAME)))
1483
0
                    {
1484
                        // Get property name
1485
0
                        std::string s = p_auxName->GetText();
1486
1487
0
                        if (std::strcmp(s.c_str(), "stderr_threshold") == 0)
1488
0
                        {
1489
                            /* Property is a `stderr_threshold` */
1490
1491
                            // Update occurrence count and check how many encountered. Only the first one applies, the
1492
                            // rest are ignored.
1493
0
                            stderr_threshold_property_count++;
1494
0
                            if (stderr_threshold_property_count > 1)
1495
0
                            {
1496
                                // Continue with the next property if `stderr_threshold` had been already specified.
1497
0
                                logError(XMLParser, classStr << " only supports one occurrence of 'stderr_threshold'."
1498
0
                                                             << " Only the first one is applied.");
1499
0
                                property = property->NextSiblingElement(PROPERTY);
1500
0
                                ret = XMLP_ret::XML_NOK;
1501
0
                                continue;
1502
0
                            }
1503
1504
                            // Get the property value. It should be a Log::Kind.
1505
0
                            if (nullptr != (p_auxValue = property->FirstChildElement(VALUE)))
1506
0
                            {
1507
                                // Get property value and use it to set the threshold.
1508
0
                                std::string threshold_str = p_auxValue->GetText();
1509
0
                                if (std::strcmp(threshold_str.c_str(), "Log::Kind::Error") == 0)
1510
0
                                {
1511
0
                                    threshold = Log::Kind::Error;
1512
0
                                }
1513
0
                                else if (std::strcmp(threshold_str.c_str(), "Log::Kind::Warning") == 0)
1514
0
                                {
1515
0
                                    threshold = Log::Kind::Warning;
1516
0
                                }
1517
0
                                else if (std::strcmp(threshold_str.c_str(), "Log::Kind::Info") == 0)
1518
0
                                {
1519
0
                                    threshold = Log::Kind::Info;
1520
0
                                }
1521
0
                                else
1522
0
                                {
1523
0
                                    logError(XMLParser, "Unkown Log::Kind '" << threshold_str
1524
0
                                                                             << "'. Using default threshold.");
1525
0
                                    ret = XMLP_ret::XML_NOK;
1526
0
                                }
1527
0
                            }
1528
0
                        }
1529
0
                        else
1530
0
                        {
1531
0
                            logError(XMLParser, "Unkown property value '" << s << "' in " << classStr
1532
0
                                                                          << " log consumer");
1533
0
                            ret = XMLP_ret::XML_NOK;
1534
0
                        }
1535
0
                    }
1536
                    // Continue with the next property
1537
0
                    property = property->NextSiblingElement(PROPERTY);
1538
0
                }
1539
1540
                // Create consumer with the specified `stderr_threshold` and register it.
1541
0
                StdoutErrConsumer* log_consumer = new StdoutErrConsumer;
1542
0
                log_consumer->stderr_threshold(threshold);
1543
0
                Log::RegisterConsumer(std::unique_ptr<LogConsumer>(log_consumer));
1544
0
            }
1545
0
        }
1546
0
        else if (std::strcmp(classStr.c_str(), "FileConsumer") == 0)
1547
0
        {
1548
0
            std::string outputFile = "output.log";
1549
0
            bool append = false;
1550
1551
0
            tinyxml2::XMLElement* property = consumer.FirstChildElement(PROPERTY);
1552
0
            if (nullptr == property)
1553
0
            {
1554
0
                Log::RegisterConsumer(std::unique_ptr<LogConsumer>(new FileConsumer));
1555
0
            }
1556
0
            else
1557
0
            {
1558
0
                tinyxml2::XMLElement* p_auxName = nullptr;
1559
0
                tinyxml2::XMLElement* p_auxValue = nullptr;
1560
0
                while (nullptr != property)
1561
0
                {
1562
                    // name - stringType
1563
0
                    if (nullptr != (p_auxName = property->FirstChildElement(NAME)))
1564
0
                    {
1565
0
                        std::string s = p_auxName->GetText();
1566
1567
0
                        if (std::strcmp(s.c_str(), "filename") == 0)
1568
0
                        {
1569
0
                            if (nullptr != (p_auxValue = property->FirstChildElement(VALUE)) &&
1570
0
                                    nullptr != p_auxValue->GetText())
1571
0
                            {
1572
0
                                outputFile = p_auxValue->GetText();
1573
0
                            }
1574
0
                            else
1575
0
                            {
1576
0
                                logError(XMLParser, "Filename value cannot be found for " << classStr
1577
0
                                                                                          << " log consumer.");
1578
0
                                ret = XMLP_ret::XML_NOK;
1579
0
                            }
1580
0
                        }
1581
0
                        else if (std::strcmp(s.c_str(), "append") == 0)
1582
0
                        {
1583
0
                            if (nullptr != (p_auxValue = property->FirstChildElement(VALUE)) &&
1584
0
                                    nullptr != p_auxValue->GetText())
1585
0
                            {
1586
0
                                std::string auxBool = p_auxValue->GetText();
1587
0
                                if (std::strcmp(auxBool.c_str(), "TRUE") == 0)
1588
0
                                {
1589
0
                                    append = true;
1590
0
                                }
1591
0
                            }
1592
0
                            else
1593
0
                            {
1594
0
                                logError(XMLParser, "Append value cannot be found for " << classStr
1595
0
                                                                                        << " log consumer.");
1596
0
                                ret = XMLP_ret::XML_NOK;
1597
0
                            }
1598
0
                        }
1599
0
                        else
1600
0
                        {
1601
0
                            logError(XMLParser, "Unknown property " << s << " in " << classStr
1602
0
                                                                    << " log consumer.");
1603
0
                            ret = XMLP_ret::XML_NOK;
1604
0
                        }
1605
0
                    }
1606
0
                    property = property->NextSiblingElement(PROPERTY);
1607
0
                }
1608
1609
0
                Log::RegisterConsumer(std::unique_ptr<LogConsumer>(new FileConsumer(outputFile, append)));
1610
0
            }
1611
0
        }
1612
0
        else
1613
0
        {
1614
0
            logError(XMLParser, "Unknown log consumer class: " << classStr);
1615
0
            ret = XMLP_ret::XML_ERROR;
1616
0
        }
1617
0
    }
1618
1619
1.56k
    return ret;
1620
1.56k
}
1621
1622
XMLP_ret XMLParser::loadXML(
1623
        const std::string& filename,
1624
        up_base_node_t& root)
1625
18.8k
{
1626
18.8k
    if (filename.empty())
1627
0
    {
1628
0
        logError(XMLPARSER, "Error loading XML file, filename empty");
1629
0
        return XMLP_ret::XML_ERROR;
1630
0
    }
1631
1632
18.8k
    tinyxml2::XMLDocument xmlDoc;
1633
18.8k
    if (tinyxml2::XMLError::XML_SUCCESS != xmlDoc.LoadFile(filename.c_str()))
1634
179
    {
1635
179
        if (filename != std::string(DEFAULT_FASTRTPS_PROFILES))
1636
179
        {
1637
179
            logError(XMLPARSER, "Error opening '" << filename << "'");
1638
179
        }
1639
179
        return XMLP_ret::XML_ERROR;
1640
179
    }
1641
1642
18.7k
    logInfo(XMLPARSER, "File '" << filename << "' opened successfully");
1643
18.7k
    return parseXML(xmlDoc, root);
1644
18.8k
}
1645
1646
XMLP_ret XMLParser::loadXMLProfiles(
1647
        tinyxml2::XMLElement& xmlDoc,
1648
        up_base_node_t& root)
1649
0
{
1650
0
    return parseXMLProfiles(xmlDoc, root);
1651
0
}
1652
1653
XMLP_ret XMLParser::loadXML(
1654
        tinyxml2::XMLDocument& xmlDoc,
1655
        up_base_node_t& root)
1656
0
{
1657
0
    return parseXML(xmlDoc, root);
1658
0
}
1659
1660
XMLP_ret XMLParser::loadXML(
1661
        const char* data,
1662
        size_t length,
1663
        up_base_node_t& root)
1664
0
{
1665
0
    tinyxml2::XMLDocument xmlDoc;
1666
0
    if (tinyxml2::XMLError::XML_SUCCESS != xmlDoc.Parse(data, length))
1667
0
    {
1668
0
        logError(XMLPARSER, "Error parsing XML buffer");
1669
0
        return XMLP_ret::XML_ERROR;
1670
0
    }
1671
0
    return parseXML(xmlDoc, root);
1672
0
}
1673
1674
template <typename T>
1675
void XMLParser::addAllAttributes(
1676
        tinyxml2::XMLElement* p_profile,
1677
        DataNode<T>& node)
1678
92.4k
{
1679
92.4k
    const tinyxml2::XMLAttribute* attrib;
1680
231k
    for (attrib = p_profile->FirstAttribute(); attrib != nullptr; attrib = attrib->Next())
1681
139k
    {
1682
139k
        node.addAttribute(attrib->Name(), attrib->Value());
1683
139k
    }
1684
92.4k
}
void eprosima::fastrtps::xmlparser::XMLParser::addAllAttributes<eprosima::fastrtps::TopicAttributes>(tinyxml2::XMLElement*, eprosima::fastrtps::xmlparser::DataNode<eprosima::fastrtps::TopicAttributes>&)
Line
Count
Source
1678
13.6k
{
1679
13.6k
    const tinyxml2::XMLAttribute* attrib;
1680
24.9k
    for (attrib = p_profile->FirstAttribute(); attrib != nullptr; attrib = attrib->Next())
1681
11.3k
    {
1682
11.3k
        node.addAttribute(attrib->Name(), attrib->Value());
1683
11.3k
    }
1684
13.6k
}
void eprosima::fastrtps::xmlparser::XMLParser::addAllAttributes<eprosima::fastrtps::ParticipantAttributes>(tinyxml2::XMLElement*, eprosima::fastrtps::xmlparser::DataNode<eprosima::fastrtps::ParticipantAttributes>&)
Line
Count
Source
1678
19.6k
{
1679
19.6k
    const tinyxml2::XMLAttribute* attrib;
1680
27.5k
    for (attrib = p_profile->FirstAttribute(); attrib != nullptr; attrib = attrib->Next())
1681
7.89k
    {
1682
7.89k
        node.addAttribute(attrib->Name(), attrib->Value());
1683
7.89k
    }
1684
19.6k
}
void eprosima::fastrtps::xmlparser::XMLParser::addAllAttributes<eprosima::fastrtps::PublisherAttributes>(tinyxml2::XMLElement*, eprosima::fastrtps::xmlparser::DataNode<eprosima::fastrtps::PublisherAttributes>&)
Line
Count
Source
1678
19.1k
{
1679
19.1k
    const tinyxml2::XMLAttribute* attrib;
1680
30.4k
    for (attrib = p_profile->FirstAttribute(); attrib != nullptr; attrib = attrib->Next())
1681
11.3k
    {
1682
11.3k
        node.addAttribute(attrib->Name(), attrib->Value());
1683
11.3k
    }
1684
19.1k
}
void eprosima::fastrtps::xmlparser::XMLParser::addAllAttributes<eprosima::fastrtps::SubscriberAttributes>(tinyxml2::XMLElement*, eprosima::fastrtps::xmlparser::DataNode<eprosima::fastrtps::SubscriberAttributes>&)
Line
Count
Source
1678
15.0k
{
1679
15.0k
    const tinyxml2::XMLAttribute* attrib;
1680
23.0k
    for (attrib = p_profile->FirstAttribute(); attrib != nullptr; attrib = attrib->Next())
1681
7.95k
    {
1682
7.95k
        node.addAttribute(attrib->Name(), attrib->Value());
1683
7.95k
    }
1684
15.0k
}
void eprosima::fastrtps::xmlparser::XMLParser::addAllAttributes<eprosima::fastrtps::RequesterAttributes>(tinyxml2::XMLElement*, eprosima::fastrtps::xmlparser::DataNode<eprosima::fastrtps::RequesterAttributes>&)
Line
Count
Source
1678
12.1k
{
1679
12.1k
    const tinyxml2::XMLAttribute* attrib;
1680
68.1k
    for (attrib = p_profile->FirstAttribute(); attrib != nullptr; attrib = attrib->Next())
1681
56.0k
    {
1682
56.0k
        node.addAttribute(attrib->Name(), attrib->Value());
1683
56.0k
    }
1684
12.1k
}
void eprosima::fastrtps::xmlparser::XMLParser::addAllAttributes<eprosima::fastrtps::ReplierAttributes>(tinyxml2::XMLElement*, eprosima::fastrtps::xmlparser::DataNode<eprosima::fastrtps::ReplierAttributes>&)
Line
Count
Source
1678
12.7k
{
1679
12.7k
    const tinyxml2::XMLAttribute* attrib;
1680
57.5k
    for (attrib = p_profile->FirstAttribute(); attrib != nullptr; attrib = attrib->Next())
1681
44.7k
    {
1682
44.7k
        node.addAttribute(attrib->Name(), attrib->Value());
1683
44.7k
    }
1684
12.7k
}
1685
1686
XMLP_ret XMLParser::fillDataNode(
1687
        tinyxml2::XMLElement* node,
1688
        DataNode<TopicAttributes>& topic_node)
1689
13.6k
{
1690
13.6k
    if (nullptr == node)
1691
0
    {
1692
0
        logError(XMLPARSER, "Bad parameters!");
1693
0
        return XMLP_ret::XML_ERROR;
1694
0
    }
1695
1696
13.6k
    addAllAttributes(node, topic_node);
1697
1698
13.6k
    uint8_t ident = 1;
1699
13.6k
    if (XMLP_ret::XML_OK != getXMLTopicAttributes(node, *topic_node.get(), ident))
1700
2.92k
    {
1701
2.92k
        return XMLP_ret::XML_ERROR;
1702
2.92k
    }
1703
1704
10.7k
    return XMLP_ret::XML_OK;
1705
13.6k
}
1706
1707
XMLP_ret XMLParser::fillDataNode(
1708
        tinyxml2::XMLElement* p_profile,
1709
        DataNode<ParticipantAttributes>& participant_node)
1710
19.6k
{
1711
    /*
1712
        <xs:complexType name="rtpsParticipantAttributesType">
1713
            <xs:all minOccurs="0">
1714
                <xs:element name="domainId" type="uint32Type" minOccurs="0"/>
1715
                <xs:element name="allocation" type="rtpsParticipantAllocationAttributesType" minOccurs="0"/>
1716
                <xs:element name="prefix" type="guid" minOccurs="0"/>
1717
                <xs:element name="defaultUnicastLocatorList" type="locatorListType" minOccurs="0"/>
1718
                <xs:element name="defaultMulticastLocatorList" type="locatorListType" minOccurs="0"/>
1719
                <xs:element name="sendSocketBufferSize" type="uint32Type" minOccurs="0"/>
1720
                <xs:element name="listenSocketBufferSize" type="uint32Type" minOccurs="0"/>
1721
                <xs:element name="builtin" type="builtinAttributesType" minOccurs="0"/>
1722
                <xs:element name="port" type="portType" minOccurs="0"/>
1723
                <xs:element name="userData" type="octetVectorType" minOccurs="0"/>
1724
                <xs:element name="participantID" type="int32Type" minOccurs="0"/>
1725
                <xs:element name="throughputController" type="throughputControllerType" minOccurs="0"/>
1726
                <xs:element name="userTransports" type="stringListType" minOccurs="0"/>
1727
                <xs:element name="useBuiltinTransports" type="boolType" minOccurs="0"/>
1728
                <xs:element name="propertiesPolicy" type="propertyPolicyType" minOccurs="0"/>
1729
                <xs:element name="name" type="stringType" minOccurs="0"/>
1730
            </xs:all>
1731
        </xs:complexType>
1732
     */
1733
1734
19.6k
    if (nullptr == p_profile)
1735
0
    {
1736
0
        logError(XMLPARSER, "Bad parameters!");
1737
0
        return XMLP_ret::XML_ERROR;
1738
0
    }
1739
1740
19.6k
    addAllAttributes(p_profile, participant_node);
1741
1742
19.6k
    uint8_t ident = 1;
1743
19.6k
    tinyxml2::XMLElement* p_element = p_profile->FirstChildElement(DOMAIN_ID);
1744
19.6k
    if (nullptr != p_element)
1745
296
    {
1746
        // domainId - uint32Type
1747
296
        if (XMLP_ret::XML_OK != getXMLUint(p_element, &participant_node.get()->domainId, ident))
1748
72
        {
1749
72
            return XMLP_ret::XML_ERROR;
1750
72
        }
1751
296
    }
1752
1753
19.5k
    p_element = p_profile->FirstChildElement(RTPS);
1754
19.5k
    if (nullptr == p_element)
1755
829
    {
1756
829
        logError(XMLPARSER, "Not found '" << RTPS << "' tag");
1757
829
        return XMLP_ret::XML_ERROR;
1758
829
    }
1759
1760
18.7k
    tinyxml2::XMLElement* p_aux0 = nullptr;
1761
18.7k
    const char* name = nullptr;
1762
22.9k
    for (p_aux0 = p_element->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
1763
18.6k
    {
1764
18.6k
        name = p_aux0->Name();
1765
1766
18.6k
        if (strcmp(name, ALLOCATION) == 0)
1767
581
        {
1768
            // allocation
1769
581
            if (XMLP_ret::XML_OK !=
1770
581
                    getXMLParticipantAllocationAttributes(p_aux0, participant_node.get()->rtps.allocation, ident))
1771
0
            {
1772
0
                return XMLP_ret::XML_ERROR;
1773
0
            }
1774
581
        }
1775
18.1k
        else if (strcmp(name, PREFIX) == 0)
1776
196
        {
1777
            // prefix
1778
196
            if (XMLP_ret::XML_OK !=
1779
196
                    getXMLguidPrefix(p_aux0, participant_node.get()->rtps.prefix, ident))
1780
196
            {
1781
196
                return XMLP_ret::XML_ERROR;
1782
196
            }
1783
196
        }
1784
17.9k
        else if (strcmp(name, DEF_UNI_LOC_LIST) == 0)
1785
287
        {
1786
            // defaultUnicastLocatorList
1787
287
            if (XMLP_ret::XML_OK !=
1788
287
                    getXMLLocatorList(p_aux0, participant_node.get()->rtps.defaultUnicastLocatorList, ident))
1789
287
            {
1790
287
                return XMLP_ret::XML_ERROR;
1791
287
            }
1792
287
        }
1793
17.6k
        else if (strcmp(name, DEF_MULTI_LOC_LIST) == 0)
1794
206
        {
1795
            // defaultMulticastLocatorList
1796
206
            if (XMLP_ret::XML_OK !=
1797
206
                    getXMLLocatorList(p_aux0, participant_node.get()->rtps.defaultMulticastLocatorList, ident))
1798
206
            {
1799
206
                return XMLP_ret::XML_ERROR;
1800
206
            }
1801
206
        }
1802
17.4k
        else if (strcmp(name, SEND_SOCK_BUF_SIZE) == 0)
1803
275
        {
1804
            // sendSocketBufferSize - uint32Type
1805
275
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &participant_node.get()->rtps.sendSocketBufferSize, ident))
1806
275
            {
1807
275
                return XMLP_ret::XML_ERROR;
1808
275
            }
1809
275
        }
1810
17.1k
        else if (strcmp(name, LIST_SOCK_BUF_SIZE) == 0)
1811
402
        {
1812
            // listenSocketBufferSize - uint32Type
1813
402
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &participant_node.get()->rtps.listenSocketBufferSize, ident))
1814
402
            {
1815
402
                return XMLP_ret::XML_ERROR;
1816
402
            }
1817
402
        }
1818
16.7k
        else if (strcmp(name, BUILTIN) == 0)
1819
12.0k
        {
1820
            // builtin
1821
12.0k
            if (XMLP_ret::XML_OK != getXMLBuiltinAttributes(p_aux0, participant_node.get()->rtps.builtin, ident))
1822
10.8k
            {
1823
10.8k
                return XMLP_ret::XML_ERROR;
1824
10.8k
            }
1825
12.0k
        }
1826
4.68k
        else if (strcmp(name, PORT) == 0)
1827
249
        {
1828
            // port
1829
249
            if (XMLP_ret::XML_OK != getXMLPortParameters(p_aux0, participant_node.get()->rtps.port, ident))
1830
0
            {
1831
0
                return XMLP_ret::XML_ERROR;
1832
0
            }
1833
249
        }
1834
4.43k
        else if (0 == strcmp(name, USER_DATA))
1835
210
        {
1836
            // userData
1837
210
            if (XMLP_ret::XML_OK != getXMLOctetVector(p_aux0, participant_node.get()->rtps.userData, ident))
1838
0
            {
1839
0
                return XMLP_ret::XML_ERROR;
1840
0
            }
1841
210
        }
1842
4.22k
        else if (strcmp(name, PART_ID) == 0)
1843
206
        {
1844
            // participantID - int32Type
1845
206
            if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &participant_node.get()->rtps.participantID, ident))
1846
206
            {
1847
206
                return XMLP_ret::XML_ERROR;
1848
206
            }
1849
206
        }
1850
4.01k
        else if (strcmp(name, THROUGHPUT_CONT) == 0)    // TODO (Ricardo) Deprecated. Remove in the future.
1851
216
        {
1852
            // throughputController
1853
216
            if (XMLP_ret::XML_OK !=
1854
216
                    getXMLThroughputController(p_aux0, participant_node.get()->rtps.throughputController, ident))
1855
0
            {
1856
0
                return XMLP_ret::XML_ERROR;
1857
0
            }
1858
216
            logWarning(XML_PARSER, THROUGHPUT_CONT << " XML tag is deprecated");
1859
216
        }
1860
3.80k
        else if (strcmp(name, USER_TRANS) == 0)
1861
328
        {
1862
            // userTransports
1863
328
            if (XMLP_ret::XML_OK != getXMLTransports(p_aux0, participant_node.get()->rtps.userTransports, ident))
1864
328
            {
1865
328
                return XMLP_ret::XML_ERROR;
1866
328
            }
1867
328
        }
1868
3.47k
        else if (strcmp(name, USE_BUILTIN_TRANS) == 0)
1869
195
        {
1870
            // useBuiltinTransports - boolType
1871
195
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &participant_node.get()->rtps.useBuiltinTransports, ident))
1872
195
            {
1873
195
                return XMLP_ret::XML_ERROR;
1874
195
            }
1875
195
        }
1876
3.27k
        else if (strcmp(name, PROPERTIES_POLICY) == 0)
1877
239
        {
1878
            // propertiesPolicy
1879
239
            if (XMLP_ret::XML_OK != getXMLPropertiesPolicy(p_aux0, participant_node.get()->rtps.properties, ident))
1880
0
            {
1881
0
                return XMLP_ret::XML_ERROR;
1882
0
            }
1883
239
        }
1884
3.03k
        else if (strcmp(name, NAME) == 0)
1885
1.59k
        {
1886
            // name - stringType
1887
1.59k
            std::string s;
1888
1.59k
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident))
1889
69
            {
1890
69
                return XMLP_ret::XML_ERROR;
1891
69
            }
1892
1.52k
            participant_node.get()->rtps.setName(s.c_str());
1893
1.52k
        }
1894
1.44k
        else
1895
1.44k
        {
1896
1.44k
            logError(XMLPARSER, "Invalid element found into 'rtpsParticipantAttributesType'. Name: " << name);
1897
1.44k
            return XMLP_ret::XML_ERROR;
1898
1.44k
        }
1899
18.6k
    }
1900
4.27k
    return XMLP_ret::XML_OK;
1901
18.7k
}
1902
1903
XMLP_ret XMLParser::fillDataNode(
1904
        tinyxml2::XMLElement* p_profile,
1905
        DataNode<PublisherAttributes>& publisher_node)
1906
19.1k
{
1907
19.1k
    if (nullptr == p_profile)
1908
0
    {
1909
0
        logError(XMLPARSER, "Bad parameters!");
1910
0
        return XMLP_ret::XML_ERROR;
1911
0
    }
1912
1913
19.1k
    addAllAttributes(p_profile, publisher_node);
1914
1915
19.1k
    uint8_t ident = 1;
1916
19.1k
    if (XMLP_ret::XML_OK != getXMLPublisherAttributes(p_profile, *publisher_node.get(), ident))
1917
11.4k
    {
1918
11.4k
        return XMLP_ret::XML_ERROR;
1919
11.4k
    }
1920
1921
7.64k
    return XMLP_ret::XML_OK;
1922
19.1k
}
1923
1924
XMLP_ret XMLParser::fillDataNode(
1925
        tinyxml2::XMLElement* p_profile,
1926
        DataNode<SubscriberAttributes>& subscriber_node)
1927
15.0k
{
1928
15.0k
    if (nullptr == p_profile)
1929
0
    {
1930
0
        logError(XMLPARSER, "Bad parameters!");
1931
0
        return XMLP_ret::XML_ERROR;
1932
0
    }
1933
1934
15.0k
    addAllAttributes(p_profile, subscriber_node);
1935
1936
15.0k
    uint8_t ident = 1;
1937
15.0k
    if (XMLP_ret::XML_OK != getXMLSubscriberAttributes(p_profile, *subscriber_node.get(), ident))
1938
8.51k
    {
1939
8.51k
        return XMLP_ret::XML_ERROR;
1940
8.51k
    }
1941
1942
6.58k
    return XMLP_ret::XML_OK;
1943
15.0k
}
1944
1945
XMLP_ret XMLParser::fillDataNode(
1946
        tinyxml2::XMLElement* p_profile,
1947
        DataNode<RequesterAttributes>& requester_node)
1948
12.1k
{
1949
    /*
1950
        <xs:complexType name="requesterProfileType">
1951
            <xs:all>
1952
                <xs:element name="request_topic_name" type="stringType" minOccurs="0"/>
1953
                <xs:element name="reply_topic_name" type="stringType" minOccurs="0"/>
1954
                <xs:element name="publisher" type="publisherProfileType"/>
1955
                <xs:element name="subscriber" type="subscriberProfileType"/>
1956
            </xs:all>
1957
            <xs:attribute name="profile_name" type="stringType" use="required"/>
1958
            <xs:attribute name="service_name" type="stringType" use="required"/>
1959
            <xs:attribute name="request_type" type="stringType" use="required"/>
1960
            <xs:attribute name="reply_type" type="stringType" use="required"/>
1961
        </xs:complexType>
1962
     */
1963
1964
12.1k
    if (nullptr == p_profile)
1965
0
    {
1966
0
        logError(XMLPARSER, "Bad parameters!");
1967
0
        return XMLP_ret::XML_ERROR;
1968
0
    }
1969
1970
12.1k
    addAllAttributes(p_profile, requester_node);
1971
12.1k
    auto found_attributes = requester_node.getAttributes();
1972
1973
12.1k
    auto it_attributes = found_attributes.find(SERVICE_NAME);
1974
12.1k
    if (found_attributes.end() != it_attributes)
1975
8.98k
    {
1976
8.98k
        requester_node.get()->service_name = it_attributes->second;
1977
8.98k
        requester_node.get()->request_topic_name = it_attributes->second + "_Request";
1978
8.98k
        requester_node.get()->reply_topic_name = it_attributes->second + "_Reply";
1979
8.98k
    }
1980
3.14k
    else
1981
3.14k
    {
1982
3.14k
        logError(XMLPARSER, "Not found required attribute " << SERVICE_NAME);
1983
3.14k
        return XMLP_ret::XML_ERROR;
1984
3.14k
    }
1985
1986
8.98k
    it_attributes = found_attributes.find(REQUEST_TYPE);
1987
8.98k
    if (found_attributes.end() != it_attributes)
1988
8.06k
    {
1989
8.06k
        requester_node.get()->request_type = it_attributes->second;
1990
8.06k
    }
1991
917
    else
1992
917
    {
1993
917
        logError(XMLPARSER, "Not found required attribute " << REQUEST_TYPE);
1994
917
        return XMLP_ret::XML_ERROR;
1995
917
    }
1996
1997
8.06k
    it_attributes = found_attributes.find(REPLY_TYPE);
1998
8.06k
    if (found_attributes.end() != it_attributes)
1999
7.55k
    {
2000
7.55k
        requester_node.get()->reply_type = it_attributes->second;
2001
7.55k
    }
2002
509
    else
2003
509
    {
2004
509
        logError(XMLPARSER, "Not found required attribute " << REPLY_TYPE);
2005
509
        return XMLP_ret::XML_ERROR;
2006
509
    }
2007
2008
7.55k
    uint8_t ident = 1;
2009
7.55k
    tinyxml2::XMLElement* p_aux0 = nullptr;
2010
7.55k
    const char* name = nullptr;
2011
2012
8.15k
    for (p_aux0 = p_profile->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
2013
2.34k
    {
2014
2.34k
        name = p_aux0->Name();
2015
2.34k
        if (strcmp(name, REQUEST_TOPIC_NAME) == 0)
2016
205
        {
2017
205
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &requester_node.get()->request_topic_name, ident))
2018
205
            {
2019
205
                return XMLP_ret::XML_ERROR;
2020
205
            }
2021
205
        }
2022
2.14k
        else if (strcmp(name, REPLY_TOPIC_NAME) == 0)
2023
207
        {
2024
207
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &requester_node.get()->reply_topic_name, ident))
2025
207
            {
2026
207
                return XMLP_ret::XML_ERROR;
2027
207
            }
2028
207
        }
2029
1.93k
        else if (strcmp(name, PUBLISHER) == 0)
2030
239
        {
2031
239
            if (XMLP_ret::XML_OK != getXMLPublisherAttributes(p_aux0, requester_node.get()->publisher, ident))
2032
10
            {
2033
10
                return XMLP_ret::XML_ERROR;
2034
10
            }
2035
239
        }
2036
1.69k
        else if (strcmp(name, SUBSCRIBER) == 0)
2037
564
        {
2038
564
            if (XMLP_ret::XML_OK != getXMLSubscriberAttributes(p_aux0, requester_node.get()->subscriber, ident))
2039
197
            {
2040
197
                return XMLP_ret::XML_ERROR;
2041
197
            }
2042
564
        }
2043
1.13k
        else
2044
1.13k
        {
2045
1.13k
            logError(XMLPARSER, "Not expected tag: '" << name << "'");
2046
1.13k
            return XMLP_ret::XML_ERROR;
2047
1.13k
        }
2048
2049
2.34k
    }
2050
2051
5.80k
    requester_node.get()->publisher.topic.topicDataType = requester_node.get()->request_type;
2052
5.80k
    requester_node.get()->publisher.topic.topicName = requester_node.get()->request_topic_name;
2053
2054
5.80k
    requester_node.get()->subscriber.topic.topicDataType = requester_node.get()->reply_type;
2055
5.80k
    requester_node.get()->subscriber.topic.topicName = requester_node.get()->reply_topic_name;
2056
2057
5.80k
    return XMLP_ret::XML_OK;
2058
7.55k
}
2059
2060
XMLP_ret XMLParser::fillDataNode(
2061
        tinyxml2::XMLElement* p_profile,
2062
        DataNode<ReplierAttributes>& replier_node)
2063
12.7k
{
2064
    /*
2065
        <xs:complexType name="replierProfileType">
2066
            <xs:all>
2067
                <xs:element name="request_topic_name" type="stringType" minOccurs="0"/>
2068
                <xs:element name="reply_topic_name" type="stringType" minOccurs="0"/>
2069
                <xs:element name="publisher" type="publisherProfileType"/>
2070
                <xs:element name="subscriber" type="subscriberProfileType"/>
2071
            </xs:all>
2072
            <xs:attribute name="profile_name" type="stringType" use="required"/>
2073
            <xs:attribute name="service_name" type="stringType" use="required"/>
2074
            <xs:attribute name="request_type" type="stringType" use="required"/>
2075
            <xs:attribute name="reply_type" type="stringType" use="required"/>
2076
        </xs:complexType>
2077
     */
2078
2079
12.7k
    if (nullptr == p_profile)
2080
0
    {
2081
0
        logError(XMLPARSER, "Bad parameters!");
2082
0
        return XMLP_ret::XML_ERROR;
2083
0
    }
2084
2085
12.7k
    addAllAttributes(p_profile, replier_node);
2086
12.7k
    auto found_attributes = replier_node.getAttributes();
2087
2088
12.7k
    auto it_attributes = found_attributes.find(SERVICE_NAME);
2089
12.7k
    if (found_attributes.end() != it_attributes)
2090
10.0k
    {
2091
10.0k
        replier_node.get()->service_name = it_attributes->second;
2092
10.0k
        replier_node.get()->request_topic_name = it_attributes->second + "_Request";
2093
10.0k
        replier_node.get()->reply_topic_name = it_attributes->second + "_Reply";
2094
10.0k
    }
2095
2.72k
    else
2096
2.72k
    {
2097
2.72k
        logError(XMLPARSER, "Not found required attribute " << SERVICE_NAME);
2098
2.72k
        return XMLP_ret::XML_ERROR;
2099
2.72k
    }
2100
2101
10.0k
    it_attributes = found_attributes.find(REQUEST_TYPE);
2102
10.0k
    if (found_attributes.end() != it_attributes)
2103
8.44k
    {
2104
8.44k
        replier_node.get()->request_type = it_attributes->second;
2105
8.44k
    }
2106
1.61k
    else
2107
1.61k
    {
2108
1.61k
        logError(XMLPARSER, "Not found required attribute " << REQUEST_TYPE);
2109
1.61k
        return XMLP_ret::XML_ERROR;
2110
1.61k
    }
2111
2112
8.44k
    it_attributes = found_attributes.find(REPLY_TYPE);
2113
8.44k
    if (found_attributes.end() != it_attributes)
2114
7.58k
    {
2115
7.58k
        replier_node.get()->reply_type = it_attributes->second;
2116
7.58k
    }
2117
867
    else
2118
867
    {
2119
867
        logError(XMLPARSER, "Not found required attribute " << REPLY_TYPE);
2120
867
        return XMLP_ret::XML_ERROR;
2121
867
    }
2122
2123
7.58k
    uint8_t ident = 1;
2124
7.58k
    tinyxml2::XMLElement* p_aux0 = nullptr;
2125
7.58k
    const char* name = nullptr;
2126
2127
8.16k
    for (p_aux0 = p_profile->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement())
2128
2.23k
    {
2129
2.23k
        name = p_aux0->Name();
2130
2.23k
        if (strcmp(name, REQUEST_TOPIC_NAME) == 0)
2131
315
        {
2132
315
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &replier_node.get()->request_topic_name, ident))
2133
315
            {
2134
315
                return XMLP_ret::XML_ERROR;
2135
315
            }
2136
315
        }
2137
1.92k
        else if (strcmp(name, REPLY_TOPIC_NAME) == 0)
2138
221
        {
2139
221
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &replier_node.get()->reply_topic_name, ident))
2140
221
            {
2141
221
                return XMLP_ret::XML_ERROR;
2142
221
            }
2143
221
        }
2144
1.70k
        else if (strcmp(name, PUBLISHER) == 0)
2145
386
        {
2146
386
            if (XMLP_ret::XML_OK != getXMLPublisherAttributes(p_aux0, replier_node.get()->publisher, ident))
2147
68
            {
2148
68
                return XMLP_ret::XML_ERROR;
2149
68
            }
2150
386
        }
2151
1.31k
        else if (strcmp(name, SUBSCRIBER) == 0)
2152
458
        {
2153
458
            if (XMLP_ret::XML_OK != getXMLSubscriberAttributes(p_aux0, replier_node.get()->subscriber, ident))
2154
195
            {
2155
195
                return XMLP_ret::XML_ERROR;
2156
195
            }
2157
458
        }
2158
859
        else
2159
859
        {
2160
859
            logError(XMLPARSER, "Not expected tag: '" << name << "'");
2161
859
            return XMLP_ret::XML_ERROR;
2162
859
        }
2163
2.23k
    }
2164
2165
5.92k
    replier_node.get()->subscriber.topic.topicDataType = replier_node.get()->request_type;
2166
5.92k
    replier_node.get()->subscriber.topic.topicName = replier_node.get()->request_topic_name;
2167
2168
5.92k
    replier_node.get()->publisher.topic.topicDataType = replier_node.get()->reply_type;
2169
5.92k
    replier_node.get()->publisher.topic.topicName = replier_node.get()->reply_topic_name;
2170
2171
5.92k
    return XMLP_ret::XML_OK;
2172
7.58k
}
2173
2174
} // namespace xmlparser
2175
} // namespace fastrtps
2176
} // namespace eprosima