Project

General

Profile

opcuaDS.patch

André Neto, 03.03.2025 10:43

View differences:

Source/Components/DataSources/OPCUADataSource/OPCUADSInput.cpp
11 11
 * You may not use this work except in compliance with the Licence.
12 12
 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
13 13
 *
14
 * @warning Unless required by applicable law or agreed to in writing, 
14
 * @warning Unless required by applicable law or agreed to in writing,
15 15
 * software distributed under the Licence is distributed on an "AS IS"
16 16
 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
17 17
 * or implied. See the Licence permissions and limitations under the Licence.
18 18

  
19 19
 * @details This source file contains the definition of all the methods for
20
 * the class OPCUADSInput (public, protected, and private). Be aware that some 
20
 * the class OPCUADSInput (public, protected, and private). Be aware that some
21 21
 * methods, such as those inline could be defined on the header file, instead.
22 22
 */
23 23

  
......
44 44
/*---------------------------------------------------------------------------*/
45 45
/*-e909 and -e9133 redefines bool. -e578 symbol ovveride in CLASS_REGISTER*/
46 46
/*lint -save -e909 -e9133 -e578*/
47
namespace MARTe {
48

  
49
OPCUADSInput::OPCUADSInput() :
50
        DataSourceI(),
51
        EmbeddedServiceMethodBinderI(),
52
        executor(*this) {
53
    masterClient = NULL_PTR(OPCUAClientRead*);
54
    nOfSignals = 0u;
55
    numberOfNodes = 0u;
56
    paths = NULL_PTR(StreamString*);
57
    extensionObject = NULL_PTR(StreamString*);
58
    structuredTypeNames = NULL_PTR(StreamString*);
59
    namespaceIndexes = NULL_PTR(uint16*);
60
    tempPaths = NULL_PTR(StreamString*);
61
    tempNamespaceIndexes = NULL_PTR(uint16*);
62
    serverAddress = "";
63
    readMode = "";
64
    sync = "";
65
    samplingTime = 0.0;
66
    nElements = NULL_PTR(uint32*);
67
    tempNElements = NULL_PTR(uint32*);
68
    entryArrayElements = NULL_PTR(uint32*);
69
    entryNumberOfMembers = NULL_PTR(uint32*);
70
    entryArraySize = 0u;
71
    types = NULL_PTR(TypeDescriptor*);
72
    entryTypes = NULL_PTR(TypeDescriptor*);
73
    cpuMask = 0xffu;
74
    stackSize = THREADS_DEFAULT_STACKSIZE;
75
    authenticate = false;
76
    username = "";
77
    password = "";
78
}
79

  
80
/*lint -e{1551} must stop the SingleThreadService in the destructor.*/
81
OPCUADSInput::~OPCUADSInput() {
82
    (void) executor.Stop();
83
    if (masterClient != NULL_PTR(OPCUAClientRead*)) {
84
        delete masterClient;
85
    }
86
    if (nElements != NULL_PTR(uint32*)) {
87
        delete[] nElements;
88
    }
89
    if (tempNElements != NULL_PTR(uint32*)) {
90
        delete[] tempNElements;
91
    }
92
    if (types != NULL_PTR(TypeDescriptor*)) {
93
        delete[] types;
94
    }
95
    if (namespaceIndexes != NULL_PTR(uint16*)) {
96
        delete[] namespaceIndexes;
97
    }
98
    if (paths != NULL_PTR(StreamString*)) {
99
        delete[] paths;
100
    }
101
    if (extensionObject != NULL_PTR(StreamString*)) {
102
        delete[] extensionObject;
103
    }
104
    if (structuredTypeNames != NULL_PTR(StreamString*)) {
105
        delete[] structuredTypeNames;
106
    }
107
    if (tempPaths != NULL_PTR(StreamString*)) {
108
        delete[] tempPaths;
109
    }
110
    if (tempNamespaceIndexes != NULL_PTR(uint16*)) {
111
        delete[] tempNamespaceIndexes;
47
namespace MARTe
48
{
49

  
50
    OPCUADSInput::OPCUADSInput() : DataSourceI(),
51
                                   EmbeddedServiceMethodBinderI(),
52
                                   executor(*this)
53
    {
54
        masterClient = NULL_PTR(OPCUAClientRead *);
55
        nOfSignals = 0u;
56
        numberOfNodes = 0u;
57
        paths = NULL_PTR(StreamString *);
58
        extensionObject = NULL_PTR(StreamString *);
59
        structuredTypeNames = NULL_PTR(StreamString *);
60
        namespaceIndexes = NULL_PTR(uint16 *);
61
        tempPaths = NULL_PTR(StreamString *);
62
        tempNamespaceIndexes = NULL_PTR(uint16 *);
63
        serverAddress = "";
64
        readMode = "";
65
        sync = "";
66
        samplingTime = 0.0;
67
        nElements = NULL_PTR(uint32 *);
68
        tempNElements = NULL_PTR(uint32 *);
69
        entryArrayElements = NULL_PTR(uint32 *);
70
        entryNumberOfMembers = NULL_PTR(uint32 *);
71
        entryArraySize = 0u;
72
        types = NULL_PTR(TypeDescriptor *);
73
        entryTypes = NULL_PTR(TypeDescriptor *);
74
        cpuMask = 0xffu;
75
        stackSize = THREADS_DEFAULT_STACKSIZE;
76
        authenticate = false;
77
        username = "";
78
        password = "";
112 79
    }
113
    if (entryArrayElements != NULL_PTR(uint32*)) {
114
        delete[] entryArrayElements;
115
    }
116
    if (entryNumberOfMembers != NULL_PTR(uint32*)) {
117
        delete[] entryNumberOfMembers;
118
    }
119
    if (entryTypes != NULL_PTR(TypeDescriptor*)) {
120
        delete[] entryTypes;
121
    }
122

  
123
}
124 80

  
125
bool OPCUADSInput::Initialise(StructuredDataI &data) {
126
    bool ok = DataSourceI::Initialise(data);
127
    if (ok) {
128
        ok = data.Read("Address", serverAddress);
129
        if (!ok) {
130
            REPORT_ERROR(ErrorManagement::ParametersError, "Cannot read the Address attribute");
81
    /*lint -e{1551} must stop the SingleThreadService in the destructor.*/
82
    OPCUADSInput::~OPCUADSInput()
83
    {
84
        (void)executor.Stop();
85
        if (masterClient != NULL_PTR(OPCUAClientRead *))
86
        {
87
            delete masterClient;
131 88
        }
132
        if (ok) {
133
            ok = data.Read("ReadMode", readMode);
134
            if (!ok) {
135
                readMode = "Read";
136
                REPORT_ERROR(ErrorManagement::Information, "ReadMode option is not enabled. Using Service Read.");
137
                ok = true;
138
            }
89
        if (nElements != NULL_PTR(uint32 *))
90
        {
91
            delete[] nElements;
139 92
        }
140
        if (ok) {
141
            ok = data.Read("Synchronise", sync);
142
            if (!ok) {
143
                sync = "no";
144
                REPORT_ERROR(ErrorManagement::Information, "Synchronise option is not enabled. Using SingleThreadService.");
145
                ok = true;
146
            }
93
        if (tempNElements != NULL_PTR(uint32 *))
94
        {
95
            delete[] tempNElements;
147 96
        }
148
        if (sync == "no") {
149
            if (ok) {
150
                ok = data.Read("CpuMask", cpuMask);
151
                if (!ok) {
152
                    REPORT_ERROR(ErrorManagement::Information, "CpuMask not set. Using default.");
153
                }
154
                ok = true;
155
            }
156
            if (ok) {
157
                ok = data.Read("StackSize", stackSize);
158
                if (!ok) {
159
                    REPORT_ERROR(ErrorManagement::Information, "StackSize not set. Using default.");
160
                }
161
                ok = true;
162
            }
97
        if (types != NULL_PTR(TypeDescriptor *))
98
        {
99
            delete[] types;
163 100
        }
164
        if (ok) {
165
            ok = data.Read("SamplingTime", samplingTime);
166
            if (!ok) {
167
                REPORT_ERROR(ErrorManagement::Information, "Sampling Time not set. Using default value: 250ms");
168
                samplingTime = 250.0;
169
                ok = true;
170
            }
101
        if (namespaceIndexes != NULL_PTR(uint16 *))
102
        {
103
            delete[] namespaceIndexes;
171 104
        }
172
        StreamString authentication;
173
        if (ok) {
174
            if (!data.Read("Authentication", authentication)) {
175
                authentication = "None";
176
                REPORT_ERROR(ErrorManagement::Warning, "'Authentication' not defined.");
177
            }
105
        if (paths != NULL_PTR(StreamString *))
106
        {
107
            delete[] paths;
178 108
        }
179
        if (ok) {
180
            if (authentication == "None") {
181
                authenticate = false;
182
                REPORT_ERROR(ErrorManagement::Information, "Using 'None' authentication.");
183
            }
184
            else if (authentication == "UserPassword") {
185
                authenticate = true;
186
                REPORT_ERROR(ErrorManagement::Information, "Using 'UserPassword' authentication.");
109
        if (extensionObject != NULL_PTR(StreamString *))
110
        {
111
            delete[] extensionObject;
112
        }
113
        if (structuredTypeNames != NULL_PTR(StreamString *))
114
        {
115
            delete[] structuredTypeNames;
116
        }
117
        if (tempPaths != NULL_PTR(StreamString *))
118
        {
119
            delete[] tempPaths;
120
        }
121
        if (tempNamespaceIndexes != NULL_PTR(uint16 *))
122
        {
123
            delete[] tempNamespaceIndexes;
124
        }
125
        if (entryArrayElements != NULL_PTR(uint32 *))
126
        {
127
            delete[] entryArrayElements;
128
        }
129
        if (entryNumberOfMembers != NULL_PTR(uint32 *))
130
        {
131
            delete[] entryNumberOfMembers;
132
        }
133
        if (entryTypes != NULL_PTR(TypeDescriptor *))
134
        {
135
            delete[] entryTypes;
136
        }
137
    }
138

  
139
    bool OPCUADSInput::Initialise(StructuredDataI &data)
140
    {
141
        bool ok = DataSourceI::Initialise(data);
142
        if (ok)
143
        {
144
            ok = data.Read("Address", serverAddress);
145
            if (!ok)
146
            {
147
                REPORT_ERROR(ErrorManagement::ParametersError, "Cannot read the Address attribute");
187 148
            }
188
            else {
189
                ok = false;
190
                REPORT_ERROR(ErrorManagement::ParametersError, "'Authentication' parameter invalid (expected 'None' or 'UserPassword')!");
149
            if (ok)
150
            {
151
                ok = data.Read("ReadMode", readMode);
152
                if (!ok)
153
                {
154
                    readMode = "Read";
155
                    REPORT_ERROR(ErrorManagement::Information, "ReadMode option is not enabled. Using Service Read.");
156
                    ok = true;
157
                }
191 158
            }
192
        }
193
        if (ok && authenticate) {
194
            StreamString userPasswordFile;
195
            ok = data.Read("UserPasswordFile", userPasswordFile);
196
            if (!ok) {
197
                REPORT_ERROR_STATIC(ErrorManagement::ParametersError, "'UserPasswordFile' not defined!");
159
            if (ok)
160
            {
161
                ok = data.Read("Synchronise", sync);
162
                if (!ok)
163
                {
164
                    sync = "no";
165
                    REPORT_ERROR(ErrorManagement::Information, "Synchronise option is not enabled. Using SingleThreadService.");
166
                    ok = true;
167
                }
198 168
            }
199
            File f;
200
            if (ok) {
201
                (void) userPasswordFile.Seek(0LLU);
202
                ok = f.Open(userPasswordFile.Buffer(), BasicFile::ACCESS_MODE_R);
203
                if (!ok) {
204
                    REPORT_ERROR_STATIC(ErrorManagement::ParametersError, "Failed to open the file at path '%s'!", userPasswordFile.Buffer());
169
            if (sync == "no")
170
            {
171
                if (ok)
172
                {
173
                    ok = data.Read("CpuMask", cpuMask);
174
                    if (!ok)
175
                    {
176
                        REPORT_ERROR(ErrorManagement::Information, "CpuMask not set. Using default.");
177
                    }
178
                    ok = true;
179
                }
180
                if (ok)
181
                {
182
                    ok = data.Read("StackSize", stackSize);
183
                    if (!ok)
184
                    {
185
                        REPORT_ERROR(ErrorManagement::Information, "StackSize not set. Using default.");
186
                    }
187
                    ok = true;
205 188
                }
206 189
            }
207
            if (ok) {
208
                ok = ReadAuthenticationKey(f, username, password);
190
            if (ok)
191
            {
192
                ok = data.Read("SamplingTime", samplingTime);
193
                if (!ok)
194
                {
195
                    REPORT_ERROR(ErrorManagement::Information, "Sampling Time not set. Using default value: 250ms");
196
                    samplingTime = 250.0;
197
                    ok = true;
198
                }
209 199
            }
210
            if (f.IsOpen()) {
211
                ok = f.Close();
212
                if (!ok) {
213
                    REPORT_ERROR_STATIC(ErrorManagement::ParametersError, "Failed to close the 'UserPasswordFile'!");
200
            StreamString authentication;
201
            if (ok)
202
            {
203
                if (!data.Read("Authentication", authentication))
204
                {
205
                    authentication = "None";
206
                    REPORT_ERROR(ErrorManagement::Warning, "'Authentication' not defined.");
214 207
                }
215 208
            }
216
        }
217
        if (ok) {
218
            ok = data.MoveRelative("Signals");
219
            if (!ok) {
220
                REPORT_ERROR(ErrorManagement::ParametersError, "Could not move to the Signals section");
209
            if (ok)
210
            {
211
                if (authentication == "None")
212
                {
213
                    authenticate = false;
214
                    REPORT_ERROR(ErrorManagement::Information, "Using 'None' authentication.");
215
                }
216
                else if (authentication == "UserPassword")
217
                {
218
                    authenticate = true;
219
                    REPORT_ERROR(ErrorManagement::Information, "Using 'UserPassword' authentication.");
220
                }
221
                else
222
                {
223
                    ok = false;
224
                    REPORT_ERROR(ErrorManagement::ParametersError, "'Authentication' parameter invalid (expected 'None' or 'UserPassword')!");
225
                }
221 226
            }
222
        }
223
        if (ok) {
224
            ok = signalsDatabase.MoveRelative("Signals");
225
        }
226
        /* Do not allow to add signals in run-time */
227
        if (ok) {
228
            ok = signalsDatabase.Write("Locked", 1u);
229
            nOfSignals = (signalsDatabase.GetNumberOfChildren() - 1u);
230
            tempPaths = new StreamString[nOfSignals];
231
            tempNamespaceIndexes = new uint16[nOfSignals];
232
            extensionObject = new StreamString[nOfSignals];
233
            tempNElements = new uint32[nOfSignals];
234
            for (uint32 i = 0u; (i < nOfSignals) && (ok); i++) {
235
                ok = signalsDatabase.MoveRelative(signalsDatabase.GetChildName(i));
236
                if (ok) {
237
                    ok = signalsDatabase.Read("Path", tempPaths[i]);
238
                    if (!ok) {
239
                        uint32 k = i;
240
                        REPORT_ERROR(ErrorManagement::ParametersError, "Cannot read the Path attribute from signal %d", k);
241
                    }
227
            if (ok && authenticate)
228
            {
229
                StreamString userPasswordFile;
230
                ok = data.Read("UserPasswordFile", userPasswordFile);
231
                if (!ok)
232
                {
233
                    REPORT_ERROR_STATIC(ErrorManagement::ParametersError, "'UserPasswordFile' not defined!");
242 234
                }
243
                if (ok) {
244
                    ok = signalsDatabase.Read("NamespaceIndex", tempNamespaceIndexes[i]);
245
                    if (!ok) {
246
                        uint32 k = i;
247
                        REPORT_ERROR(ErrorManagement::ParametersError, "Cannot read the NamespaceIndex attribute from signal %d", k);
235
                File f;
236
                if (ok)
237
                {
238
                    (void)userPasswordFile.Seek(0LLU);
239
                    ok = f.Open(userPasswordFile.Buffer(), BasicFile::ACCESS_MODE_R);
240
                    if (!ok)
241
                    {
242
                        REPORT_ERROR_STATIC(ErrorManagement::ParametersError, "Failed to open the file at path '%s'!", userPasswordFile.Buffer());
248 243
                    }
249 244
                }
250
                if (ok) {
251
                    ok = signalsDatabase.Read("NumberOfElements", tempNElements[i]);
252
                    if (!ok) {
253
                        tempNElements[i] = 1u;
254
                        ok = true;
255
                        uint32 k = i;
256
                        REPORT_ERROR(ErrorManagement::Information, "No NumberOfElements set up for signal %d. Using N = 1", k);
245
                if (ok)
246
                {
247
                    ok = ReadAuthenticationKey(f, username, password);
248
                }
249
                if (f.IsOpen())
250
                {
251
                    ok = f.Close();
252
                    if (!ok)
253
                    {
254
                        REPORT_ERROR_STATIC(ErrorManagement::ParametersError, "Failed to close the 'UserPasswordFile'!");
257 255
                    }
258 256
                }
259
                if (ok) {
260
                    ok = signalsDatabase.Read("ExtensionObject", extensionObject[i]);
261
                    if ((extensionObject[i] == "yes") && ok) {
262
                        structuredTypeNames = new StreamString[nOfSignals];
263
                        ok = signalsDatabase.Read("Type", structuredTypeNames[i]);
264
                        if (!ok) {
257
            }
258
            if (ok)
259
            {
260
                ok = data.MoveRelative("Signals");
261
                if (!ok)
262
                {
263
                    REPORT_ERROR(ErrorManagement::ParametersError, "Could not move to the Signals section");
264
                }
265
            }
266
            if (ok)
267
            {
268
                ok = signalsDatabase.MoveRelative("Signals");
269
            }
270
            /* Do not allow to add signals in run-time */
271
            if (ok)
272
            {
273
                ok = signalsDatabase.Write("Locked", 1u);
274
                nOfSignals = (signalsDatabase.GetNumberOfChildren() - 1u);
275
                tempPaths = new StreamString[nOfSignals];
276
                tempNamespaceIndexes = new uint16[nOfSignals];
277
                extensionObject = new StreamString[nOfSignals];
278
                tempNElements = new uint32[nOfSignals];
279
                for (uint32 i = 0u; (i < nOfSignals) && (ok); i++)
280
                {
281
                    ok = signalsDatabase.MoveRelative(signalsDatabase.GetChildName(i));
282
                    if (ok)
283
                    {
284
                        ok = signalsDatabase.Read("Path", tempPaths[i]);
285
                        if (!ok)
286
                        {
265 287
                            uint32 k = i;
266
                            REPORT_ERROR(ErrorManagement::ParametersError, "Cannot read the Type attribute from signal %d", k);
288
                            REPORT_ERROR(ErrorManagement::ParametersError, "Cannot read the Path attribute from signal %d", k);
267 289
                        }
268
                        REPORT_ERROR(ErrorManagement::Information, "Reading Structure with OPC UA Complex DataType Extension");
269 290
                    }
270
                    else {
271
                        extensionObject[i] = "no";
272
                        ok = true;
291
                    if (ok)
292
                    {
293
                        ok = signalsDatabase.Read("NamespaceIndex", tempNamespaceIndexes[i]);
294
                        if (!ok)
295
                        {
296
                            uint32 k = i;
297
                            REPORT_ERROR(ErrorManagement::ParametersError, "Cannot read the NamespaceIndex attribute from signal %d", k);
298
                        }
299
                    }
300
                    if (ok)
301
                    {
302
                        ok = signalsDatabase.Read("NumberOfElements", tempNElements[i]);
303
                        if (!ok)
304
                        {
305
                            tempNElements[i] = 1u;
306
                            ok = true;
307
                            uint32 k = i;
308
                            REPORT_ERROR(ErrorManagement::Information, "No NumberOfElements set up for signal %d. Using N = 1", k);
309
                        }
310
                    }
311
                    if (ok)
312
                    {
313
                        ok = signalsDatabase.Read("ExtensionObject", extensionObject[i]);
314
                        if ((extensionObject[i] == "yes") && ok)
315
                        {
316
                            structuredTypeNames = new StreamString[nOfSignals];
317
                            ok = signalsDatabase.Read("Type", structuredTypeNames[i]);
318
                            if (!ok)
319
                            {
320
                                uint32 k = i;
321
                                REPORT_ERROR(ErrorManagement::ParametersError, "Cannot read the Type attribute from signal %d", k);
322
                            }
323
                            REPORT_ERROR(ErrorManagement::Information, "Reading Structure with OPC UA Complex DataType Extension");
324
                        }
325
                        else
326
                        {
327
                            extensionObject[i] = "no";
328
                            ok = true;
329
                        }
330
                    }
331
                    if (ok)
332
                    {
333
                        ok = signalsDatabase.MoveToAncestor(1u);
273 334
                    }
274
                }
275
                if (ok) {
276
                    ok = signalsDatabase.MoveToAncestor(1u);
277 335
                }
278 336
            }
279
        }
280
        if (ok) {
281
            ok = signalsDatabase.MoveToAncestor(1u);
282
        }
283
        if (ok) {
284
            ok = data.MoveToAncestor(1u);
285
        }
286
    }
287
    if (!ok) {
288
        REPORT_ERROR(ErrorManagement::ParametersError, "Error during Initialise!");
289
    }
290
    return ok;
291
}
292

  
293
bool OPCUADSInput::SetConfiguredDatabase(StructuredDataI &data) {
294
    bool ok = DataSourceI::SetConfiguredDatabase(data);
295
    numberOfNodes = GetNumberOfSignals();
296
    uint8 nDimensions = 0u;
297
    nElements = new uint32[numberOfNodes];
298
    types = new TypeDescriptor[numberOfNodes];
299
    StreamString signalName;
300
    /* Check for signals with number of dimensions > 1. Multidimensional arrays not supported yet */
301
    for (uint32 k = 0u; k < numberOfNodes; k++) {
302
        ok = GetSignalNumberOfDimensions(k, nDimensions);
303
        if ((nDimensions > 1u) && ok) {
304
            ok = GetSignalName(k, signalName);
305
            if (ok) {
306
                REPORT_ERROR(ErrorManagement::ParametersError, "Signal %s has Number Of Dimensions = %d. Multidimensional arrays not supported yet.",
307
                             signalName.Buffer(), nDimensions);
308
                ok = false;
337
            if (ok)
338
            {
339
                ok = signalsDatabase.MoveToAncestor(1u);
340
            }
341
            if (ok)
342
            {
343
                ok = data.MoveToAncestor(1u);
309 344
            }
310 345
        }
311
        if (ok) {
312
            ok = GetSignalNumberOfElements(k, nElements[k]);
313
        }
314
        if (ok) {
315
            types[k] = GetSignalType(k);
346
        if (!ok)
347
        {
348
            REPORT_ERROR(ErrorManagement::ParametersError, "Error during Initialise!");
316 349
        }
317
        signalName = "";
350
        return ok;
318 351
    }
319 352

  
320
    uint32 bodyLength = 0u;
321
    if (structuredTypeNames != NULL_PTR(StreamString*)) {
322
        for (uint32 k = 0u; k < nOfSignals; k++) {
323
            const ClassRegistryItem *cri = ClassRegistryDatabase::Instance()->Find(structuredTypeNames[k].Buffer());
324
            if (cri != NULL_PTR(const ClassRegistryItem*)) {
325
                const Introspection *intro = cri->GetIntrospection();
326
                ok = (intro != NULL_PTR(const Introspection*));
327
                if (ok) {
328
                    GetStructureDimensions(intro, entryArraySize);
329

  
330
                    entryArrayElements = new uint32[entryArraySize];
331
                    entryNumberOfMembers = new uint32[entryArraySize];
332
                    entryTypes = new TypeDescriptor[entryArraySize];
333

  
334
                    uint32 index = 0u;
335
                    ok = GetStructure(intro, entryArrayElements, entryTypes, entryNumberOfMembers, index);
336
                    if (ok) {
337
                        ok = GetBodyLength(intro, bodyLength);
338
                    }
339
                    if (ok) {
340
                        bodyLength *= tempNElements[k];
353
    bool OPCUADSInput::SetConfiguredDatabase(StructuredDataI &data)
354
    {
355
        bool ok = DataSourceI::SetConfiguredDatabase(data);
356
        numberOfNodes = GetNumberOfSignals();
357
        uint8 nDimensions = 0u;
358
        nElements = new uint32[numberOfNodes];
359
        types = new TypeDescriptor[numberOfNodes];
360
        StreamString signalName;
361
        /* Check for signals with number of dimensions > 1. Multidimensional arrays not supported yet */
362
        for (uint32 k = 0u; k < numberOfNodes; k++)
363
        {
364
            ok = GetSignalNumberOfDimensions(k, nDimensions);
365
            if ((nDimensions > 1u) && ok)
366
            {
367
                ok = GetSignalName(k, signalName);
368
                if (ok)
369
                {
370
                    REPORT_ERROR(ErrorManagement::ParametersError, "Signal %s has Number Of Dimensions = %d. Multidimensional arrays not supported yet.",
371
                                 signalName.Buffer(), nDimensions);
372
                    ok = false;
373
                }
374
            }
375
            if (ok)
376
            {
377
                ok = GetSignalNumberOfElements(k, nElements[k]);
378
            }
379
            if (ok)
380
            {
381
                types[k] = GetSignalType(k);
382
            }
383
            signalName = "";
384
        }
385

  
386
        uint32 bodyLength = 0u;
387
        if (structuredTypeNames != NULL_PTR(StreamString *))
388
        {
389
            for (uint32 k = 0u; k < nOfSignals; k++)
390
            {
391
                const ClassRegistryItem *cri = ClassRegistryDatabase::Instance()->Find(structuredTypeNames[k].Buffer());
392
                if (cri != NULL_PTR(const ClassRegistryItem *))
393
                {
394
                    const Introspection *intro = cri->GetIntrospection();
395
                    ok = (intro != NULL_PTR(const Introspection *));
396
                    if (ok)
397
                    {
398
                        GetStructureDimensions(intro, entryArraySize);
399

  
400
                        entryArrayElements = new uint32[entryArraySize];
401
                        entryNumberOfMembers = new uint32[entryArraySize];
402
                        entryTypes = new TypeDescriptor[entryArraySize];
403

  
404
                        uint32 index = 0u;
405
                        ok = GetStructure(intro, entryArrayElements, entryTypes, entryNumberOfMembers, index);
406
                        if (ok)
407
                        {
408
                            ok = GetBodyLength(intro, bodyLength);
409
                        }
410
                        if (ok)
411
                        {
412
                            bodyLength *= tempNElements[k];
413
                        }
341 414
                    }
342 415
                }
343 416
            }
344 417
        }
345
    }
346
    if (extensionObject != NULL_PTR(StreamString*)) {
347
        if (extensionObject[0u] == "no") {
348
            if (ok) {
349
                paths = new StreamString[numberOfNodes];
350
                namespaceIndexes = new uint16[numberOfNodes];
351
                StreamString sigName;
352
                StreamString pathToken;
353
                StreamString sigToken;
354
                char8 ignore;
355
                for (uint32 i = 0u; i < numberOfNodes; i++) {
356
                    sigName = "";
357
                    /* Getting the first name from the signal path */
358
                    ok = GetSignalName(i, sigName);
359
                    if (ok) {
360
                        ok = sigName.Seek(0LLU);
361
                    }
362
                    if (ok) {
363
                        ok = sigName.GetToken(sigToken, ".", ignore);
364
                    }
365
                    if (ok) {
366
                        for (uint32 j = 0u; j < nOfSignals; j++) {
367
                            StreamString lastToken;
368
                            sigToken = "";
369
                            if (tempPaths != NULL_PTR(StreamString*)) {
370
                                ok = tempPaths[j].Seek(0LLU);
371
                                if (ok) {
372
                                    do {
373
                                        ok = tempPaths[j].GetToken(lastToken, ".", ignore);
374
                                        if (ok) {
375
                                            sigToken = lastToken;
376
                                        }
377
                                        lastToken = "";
418
        if (extensionObject != NULL_PTR(StreamString *))
419
        {
420
            if (extensionObject[0u] == "no")
421
            {
422
                if (ok)
423
                {
424
                    paths = new StreamString[numberOfNodes];
425
                    namespaceIndexes = new uint16[numberOfNodes];
426
                    StreamString sigName;
427
                    StreamString pathToken;
428
                    StreamString sigToken;
429
                    char8 ignore;
430
                    for (uint32 i = 0u; i < numberOfNodes; i++)
431
                    {
432
                        sigName = "";
433
                        /* Getting the first name from the signal path */
434
                        ok = GetSignalName(i, sigName);
435
                        if (ok)
436
                        {
437
                            ok = sigName.Seek(0LLU);
438
                        }
439
                        if (ok)
440
                        {
441
                            ok = sigName.GetToken(sigToken, ".", ignore);
442
                        }
443
                        if (ok)
444
                        {
445
                            for (uint32 j = 0u; j < nOfSignals; j++)
446
                            {
447
                                StreamString lastToken;
448
                                sigToken = "";
449
                                if (tempPaths != NULL_PTR(StreamString *))
450
                                {
451
                                    ok = tempPaths[j].Seek(0LLU);
452
                                    if (ok)
453
                                    {
454
                                        do
455
                                        {
456
                                            ok = tempPaths[j].GetToken(lastToken, ".", ignore);
457
                                            if (ok)
458
                                            {
459
                                                sigToken = lastToken;
460
                                            }
461
                                            lastToken = "";
462
                                        } while (ok);
378 463
                                    }
379
                                    while (ok);
380
                                }
381
                                /* This cycle will save the last token found */
382
                                ok = tempPaths[j].Seek(0LLU);
383
                                if (ok) {
384
                                    do {
385
                                        ok = tempPaths[j].GetToken(lastToken, ".", ignore);
386
                                        if (ok) {
387
                                            sigToken = lastToken;
388
                                        }
389
                                        lastToken = "";
464
                                    /* This cycle will save the last token found */
465
                                    ok = tempPaths[j].Seek(0LLU);
466
                                    if (ok)
467
                                    {
468
                                        do
469
                                        {
470
                                            ok = tempPaths[j].GetToken(lastToken, ".", ignore);
471
                                            if (ok)
472
                                            {
473
                                                sigToken = lastToken;
474
                                            }
475
                                            lastToken = "";
476
                                        } while (ok);
390 477
                                    }
391
                                    while (ok);
392
                                }
393
                                ok = tempPaths[j].Seek(0LLU);
394
                                if (ok) {
395
                                    do {
396
                                        pathToken = "";
397
                                        ok = tempPaths[j].GetToken(pathToken, ".", ignore);
398
                                        if ((paths != NULL_PTR(StreamString*)) && ok) {
399
                                            if ((namespaceIndexes != NULL_PTR(uint16*)) && (tempNamespaceIndexes != NULL_PTR(uint16*))) {
400
                                                if (pathToken == sigToken) {
401
                                                    if (numberOfNodes == nOfSignals) {
402
                                                        paths[j] = tempPaths[j];
403
                                                        namespaceIndexes[j] = tempNamespaceIndexes[j];
478
                                    ok = tempPaths[j].Seek(0LLU);
479
                                    if (ok)
480
                                    {
481
                                        do
482
                                        {
483
                                            pathToken = "";
484
                                            ok = tempPaths[j].GetToken(pathToken, ".", ignore);
485
                                            if ((paths != NULL_PTR(StreamString *)) && ok)
486
                                            {
487
                                                if ((namespaceIndexes != NULL_PTR(uint16 *)) && (tempNamespaceIndexes != NULL_PTR(uint16 *)))
488
                                                {
489
                                                    if (pathToken == sigToken)
490
                                                    {
491
                                                        if (numberOfNodes == nOfSignals)
492
                                                        {
493
                                                            paths[j] = tempPaths[j];
494
                                                            namespaceIndexes[j] = tempNamespaceIndexes[j];
495
                                                        }
496
                                                        else
497
                                                        {
498
                                                            paths[i] = tempPaths[j];
499
                                                            namespaceIndexes[i] = tempNamespaceIndexes[j];
500
                                                        }
501
                                                        ok = false; /* Exit from the cycle */
404 502
                                                    }
405
                                                    else {
406
                                                        paths[i] = tempPaths[j];
407
                                                        namespaceIndexes[i] = tempNamespaceIndexes[j];
408
                                                    }
409
                                                    ok = false; /* Exit from the cycle */
410 503
                                                }
411 504
                                            }
412
                                        }
505
                                        } while (ok);
413 506
                                    }
414
                                    while (ok);
415 507
                                }
416

  
417 508
                            }
418
                        }
419 509

  
420
                        /* Then we add to the path the remaining node names */
421
                        StreamString dotToken = ".";
422
                        do {
423
                            sigToken = "";
424
                            ok = sigName.GetToken(sigToken, ".", ignore);
425
                            if ((paths != NULL_PTR(StreamString*)) && ok) {
426
                                paths[i] += dotToken;
427
                                paths[i] += sigToken;
428
                            }
510
                            /* Then we add to the path the remaining node names */
511
                            StreamString dotToken = ".";
512
                            do
513
                            {
514
                                sigToken = "";
515
                                ok = sigName.GetToken(sigToken, ".", ignore);
516
                                if ((paths != NULL_PTR(StreamString *)) && ok)
517
                                {
518
                                    paths[i] += dotToken;
519
                                    paths[i] += sigToken;
520
                                }
521
                            } while (ok);
522
                            ok = true;
429 523
                        }
430
                        while (ok);
431
                        ok = true;
432 524
                    }
433 525
                }
434 526
            }
435 527
        }
436
    }
437
    if (ok) {
438
        /* Setting up the master Client who will perform the operations */
439
        masterClient = new OPCUAClientRead;
440
        masterClient->SetServerAddress(serverAddress);
441
        if (authenticate) {
442
            ok = masterClient->Connect(username, password);
443
        }
444
        else {
445
            ok = masterClient->Connect();
446
        }
447
        if (!ok) {
448
            REPORT_ERROR(ErrorManagement::ParametersError, "Cannot Connect to the Server.");
449
        }
450
        if (ok) {
451
            REPORT_ERROR(ErrorManagement::Information, "The connection with the OPCUA Server has been established successfully!");
452
            if (extensionObject != NULL_PTR(StreamString*)) {
453
                if (extensionObject[0u] == "no") {
454
                    ok = masterClient->SetServiceRequest(namespaceIndexes, paths, numberOfNodes);
455
                    if (ok) {
456
                        masterClient->SetValueMemories(numberOfNodes);
457
                    }
458
                    else {
459
                        REPORT_ERROR(ErrorManagement::ParametersError, "SetServiceRequest Failed.");
528
        if (ok)
529
        {
530
            /* Setting up the master Client who will perform the operations */
531
            masterClient = new OPCUAClientRead;
532
            masterClient->SetServerAddress(serverAddress);
533
            if (authenticate)
534
            {
535
                ok = masterClient->Connect(username, password);
536
            }
537
            else
538
            {
539
                ok = masterClient->Connect();
540
            }
541
            if (!ok)
542
            {
543
                REPORT_ERROR(ErrorManagement::ParametersError, "Cannot Connect to the Server.");
544
            }
545
            if (ok)
546
            {
547
                REPORT_ERROR(ErrorManagement::Information, "The connection with the OPCUA Server has been established successfully!");
548
                if (extensionObject != NULL_PTR(StreamString *))
549
                {
550
                    if (extensionObject[0u] == "no")
551
                    {
552
                        ok = masterClient->SetServiceRequest(namespaceIndexes, paths, numberOfNodes);
553
                        if (ok)
554
                        {
555
                            masterClient->SetValueMemories(numberOfNodes);
556
                        }
557
                        else
558
                        {
559
                            REPORT_ERROR(ErrorManagement::ParametersError, "SetServiceRequest Failed.");
560
                        }
460 561
                    }
461
                }
462
                else {
463
                    ok = masterClient->SetServiceRequest(tempNamespaceIndexes, tempPaths, nOfSignals);
464
                    if (ok) {
465
                        masterClient->SetDataPtr(bodyLength);
466
                        masterClient->SetValueMemories(numberOfNodes);
467
                        for (uint32 k = 0u; k < nOfSignals; k++) {
468
                            uint32 nodeCounter = 0u;
469
                            uint32 index;
470
                            if (tempNElements != NULL_PTR(uint32*)) {
471
                                for (uint32 j = 0u; j < tempNElements[k]; j++) {
472
                                    index = 0u;
473
                                    uint32 numberOfNodesForEachIteration = (numberOfNodes / tempNElements[k]) * (j + 1u);
474
                                    while (nodeCounter < numberOfNodesForEachIteration) {
475
                                        if (ok) {
476
                                            ok = masterClient->GetExtensionObjectByteString(entryTypes, entryArrayElements, entryNumberOfMembers,
477
                                                                                            entryArraySize, nodeCounter, index);
562
                    else
563
                    {
564
                        ok = masterClient->SetServiceRequest(tempNamespaceIndexes, tempPaths, nOfSignals);
565
                        if (ok)
566
                        {
567
                            masterClient->SetDataPtr(bodyLength);
568
                            masterClient->SetValueMemories(numberOfNodes);
569
                            for (uint32 k = 0u; k < nOfSignals; k++)
570
                            {
571
                                uint32 nodeCounter = 0u;
572
                                uint32 index;
573
                                if (tempNElements != NULL_PTR(uint32 *))
574
                                {
575
                                    for (uint32 j = 0u; j < tempNElements[k]; j++)
576
                                    {
577
                                        index = 0u;
578
                                        uint32 numberOfNodesForEachIteration = (numberOfNodes / tempNElements[k]) * (j + 1u);
579
                                        while (nodeCounter < numberOfNodesForEachIteration)
580
                                        {
581
                                            if (ok)
582
                                            {
583
                                                ok = masterClient->GetExtensionObjectByteString(entryTypes, entryArrayElements, entryNumberOfMembers,
584
                                                                                                entryArraySize, nodeCounter, index);
585
                                            }
478 586
                                        }
479 587
                                    }
480 588
                                }
......
484 592
                }
485 593
            }
486 594
        }
595
        if ((sync == "no") && ok)
596
        {
597
            executor.SetCPUMask(cpuMask);
598
            executor.SetStackSize(stackSize);
599
            executor.SetName(GetName());
600
            ok = (executor.Start() == ErrorManagement::NoError);
601
        }
602
        if (!ok)
603
        {
604
            REPORT_ERROR(ErrorManagement::ParametersError, "Error during configuration.");
605
        }
606
        return ok;
487 607
    }
488
    if ((sync == "no") && ok) {
489
        executor.SetCPUMask(cpuMask);
490
        executor.SetStackSize(stackSize);
491
        executor.SetName(GetName());
492
        ok = (executor.Start() == ErrorManagement::NoError);
608

  
609
    bool OPCUADSInput::AllocateMemory()
610
    {
611
        return true;
493 612
    }
494
    if (!ok) {
495
        REPORT_ERROR(ErrorManagement::ParametersError, "Error during configuration.");
613
    /*lint -e{715}  [MISRA C++ Rule 0-1-11], [MISRA C++ Rule 0-1-12]. Justification: The signalAddress is independent of the bufferIdx.*/
614
    bool OPCUADSInput::GetSignalMemoryBuffer(const uint32 signalIdx,
615
                                             const uint32 bufferIdx,
616
                                             void *&signalAddress)
617
    {
618
        StreamString opcDisplayName;
619
        bool ok = GetSignalName(signalIdx, opcDisplayName);
620
        if (ok)
621
        {
622
            if (types != NULL_PTR(TypeDescriptor *))
623
            {
624
                /*lint -e{9007}  [MISRA C++ Rule 5-14-1] Justification: No side effects.*/
625
                if ((types[signalIdx].type == CArray) || (types[signalIdx].type == BT_CCString) || (types[signalIdx].type == PCString) || (types[signalIdx].type == SString))
626
                {
627
                    REPORT_ERROR(ErrorManagement::ParametersError, "Type String is not supported yet.");
628
                }
629
                if ((nElements != NULL_PTR(uint32 *)) && (masterClient != NULL_PTR(OPCUAClientRead *)))
630
                {
631
                    ok = masterClient->GetSignalMemory(signalAddress, signalIdx, types[signalIdx], nElements[signalIdx]);
632
                }
633
            }
634
        }
635
        if (ok)
636
        {
637
            ok = (signalAddress != NULL_PTR(void *));
638
        }
639
        return ok;
496 640
    }
497
    return ok;
498
}
499 641

  
500
bool OPCUADSInput::AllocateMemory() {
501
    return true;
502
}
503
/*lint -e{715}  [MISRA C++ Rule 0-1-11], [MISRA C++ Rule 0-1-12]. Justification: The signalAddress is independent of the bufferIdx.*/
504
bool OPCUADSInput::GetSignalMemoryBuffer(const uint32 signalIdx,
505
                                         const uint32 bufferIdx,
506
                                         void *&signalAddress) {
507
    StreamString opcDisplayName;
508
    bool ok = GetSignalName(signalIdx, opcDisplayName);
509
    if (ok) {
510
        if (types != NULL_PTR(TypeDescriptor*)) {
511
            /*lint -e{9007}  [MISRA C++ Rule 5-14-1] Justification: No side effects.*/
512
            if ((types[signalIdx].type == CArray) || (types[signalIdx].type == BT_CCString) || (types[signalIdx].type == PCString)
513
                    || (types[signalIdx].type == SString)) {
514
                REPORT_ERROR(ErrorManagement::ParametersError, "Type String is not supported yet.");
515
            }
516
            if ((nElements != NULL_PTR(uint32*)) && (masterClient != NULL_PTR(OPCUAClientRead*))) {
517
                ok = masterClient->GetSignalMemory(signalAddress, signalIdx, types[signalIdx], nElements[signalIdx]);
642
    /*lint -e{715}  [MISRA C++ Rule 0-1-11], [MISRA C++ Rule 0-1-12]. Justification: The brokerName only depends on the direction */
643
    const char8 *OPCUADSInput::GetBrokerName(StructuredDataI &data,
644
                                             const SignalDirection direction)
645
    {
646
        const char8 *brokerName = "";
647
        if (sync == "no")
648
        {
649
            if (direction == InputSignals)
650
            {
651
                brokerName = "MemoryMapInputBroker";
518 652
            }
519 653
        }
520
    }
521
    if (ok) {
522
        ok = (signalAddress != NULL_PTR(void*));
523
    }
524
    return ok;
525
}
654
        else if (sync == "yes")
655
        {
656
            if (direction == InputSignals)
657
            {
658

  
659
                uint32 tempSync = 0;
660
                if (!data.Read("SynchSignal", tempSync))
661
                {
662
                    tempSync = 0;
663
                }
664

  
665
                if (tempSync > 0)
666
                {
667
                    brokerName = "MemoryMapSynchronisedInputBroker";
668
                 
669
                }else {
670
                    brokerName = "MemoryMapInputBroker";
671
                }
526 672

  
527
/*lint -e{715}  [MISRA C++ Rule 0-1-11], [MISRA C++ Rule 0-1-12]. Justification: The brokerName only depends on the direction */
528
const char8* OPCUADSInput::GetBrokerName(StructuredDataI &data,
529
                                         const SignalDirection direction) {
530
    const char8 *brokerName = "";
531
    if (sync == "no") {
532
        if (direction == InputSignals) {
533
            brokerName = "MemoryMapInputBroker";
673
            }
534 674
        }
535
    }
536
    else if (sync == "yes") {
537
        if (direction == InputSignals) {
538
            brokerName = "MemoryMapSynchronisedInputBroker";
675
        else
676
        {
677
            REPORT_ERROR(ErrorManagement::ParametersError, "Impossible to define a broker. Check Synchronise option.");
539 678
        }
679
        return brokerName;
540 680
    }
541
    else {
542
        REPORT_ERROR(ErrorManagement::ParametersError, "Impossible to define a broker. Check Synchronise option.");
543
    }
544
    return brokerName;
545
}
546 681

  
547
/*lint -e{715}  [MISRA C++ Rule 0-1-11], [MISRA C++ Rule 0-1-12]. Justification: NOOP at StateChange, independently of the function parameters.*/
548
bool OPCUADSInput::PrepareNextState(const char8 *const currentStateName,
549
                                    const char8 *const nextStateName) {
550
    return true;
551
}
682
    /*lint -e{715}  [MISRA C++ Rule 0-1-11], [MISRA C++ Rule 0-1-12]. Justification: NOOP at StateChange, independently of the function parameters.*/
683
    bool OPCUADSInput::PrepareNextState(const char8 *const currentStateName,
684
                                        const char8 *const nextStateName)
685
    {
686
        return true;
687
    }
552 688

  
553
ErrorManagement::ErrorType OPCUADSInput::Execute(ExecutionInfo &info) {
554
    ErrorManagement::ErrorType err = ErrorManagement::NoError;
555
    if (info.GetStage() != ExecutionInfo::BadTerminationStage) {
556
        if ((types != NULL_PTR(TypeDescriptor*)) && (nElements != NULL_PTR(uint32*)) && (masterClient != NULL_PTR(OPCUAClientRead*))) {
557
            bool ok;
558
            if (readMode == "Read") {
559
                ok = masterClient->Read(types, nElements);
560
                if (!ok) {
561
                    err = ErrorManagement::CommunicationError;
689
    ErrorManagement::ErrorType OPCUADSInput::Execute(ExecutionInfo &info)
690
    {
691
        ErrorManagement::ErrorType err = ErrorManagement::NoError;
692
        if (info.GetStage() != ExecutionInfo::BadTerminationStage)
693
        {
694
            if ((types != NULL_PTR(TypeDescriptor *)) && (nElements != NULL_PTR(uint32 *)) && (masterClient != NULL_PTR(OPCUAClientRead *)))
695
            {
696
                bool ok;
697
                if (readMode == "Read")
698
                {
699
                    ok = masterClient->Read(types, nElements);
700
                    if (!ok)
701
                    {
702
                        err = ErrorManagement::CommunicationError;
703
                    }
704
                }
705
                else if (readMode == "Monitor")
706
                {
707
                    err = ErrorManagement::UnsupportedFeature;
708
                }
709
                else
710
                {
711
                    REPORT_ERROR(ErrorManagement::ParametersError, "ReadMode defines an unsupported service.");
562 712
                }
563
            }
564
            else if (readMode == "Monitor") {
565
                err = ErrorManagement::UnsupportedFeature;
566
            }
567
            else {
568
                REPORT_ERROR(ErrorManagement::ParametersError, "ReadMode defines an unsupported service.");
569 713
            }
570 714
        }
715
        Sleep::MSec(samplingTime);
716
        return err;
571 717
    }
572
    return err;
573
}
574 718

  
575
bool OPCUADSInput::Synchronise() {
576
    bool ok = true;
577
    if (sync == "yes") {
578
        if ((types != NULL_PTR(TypeDescriptor*)) && (nElements != NULL_PTR(uint32*)) && (masterClient != NULL_PTR(OPCUAClientRead*))) {
579
            if (readMode == "Read") {
580
                ok = masterClient->Read(types, nElements);
581
            }
582
            else if (readMode == "Monitor") {
583
                ok = false;
584
            }
585
            else {
586
                REPORT_ERROR(ErrorManagement::ParametersError, "ReadMode defines an unsupported service.");
719
    bool OPCUADSInput::Synchronise()
720
    {
721
        bool ok = true;
722
        if (sync == "yes")
723
        {
724
            if ((types != NULL_PTR(TypeDescriptor *)) && (nElements != NULL_PTR(uint32 *)) && (masterClient != NULL_PTR(OPCUAClientRead *)))
725
            {
726
                if (readMode == "Read")
727
                {
728
                    ok = masterClient->Read(types, nElements);
729
                }
730
                else if (readMode == "Monitor")
731
                {
732
                    ok = false;
733
                }
734
                else
735
                {
736
                    REPORT_ERROR(ErrorManagement::ParametersError, "ReadMode defines an unsupported service.");
737
                }
587 738
            }
588 739
        }
740
        return ok;
589 741
    }
590
    return ok;
591
}
592 742

  
593
const char8* OPCUADSInput::GetServerAddress() {
594
    return serverAddress.Buffer();
595
}
743
    const char8 *OPCUADSInput::GetServerAddress()
744
    {
745
        return serverAddress.Buffer();
746
    }
596 747

  
597
bool OPCUADSInput::GetBodyLength(const Introspection *const intro,
598
                                 uint32 &bodyLength) {
599
    bool ok = true;
600
    uint32 numberOfMembers = intro->GetNumberOfMembers();
601
    uint32 j;
602
    for (j = 0u; j < numberOfMembers; j++) {
603
        const IntrospectionEntry entry = intro->operator[](j);
604
        const char8 *const memberTypeName = entry.GetMemberTypeName();
605
        uint32 nElem;
606
        nElem = entry.GetNumberOfElements(0u);
607
        if (nElem > 1u) {
608
            bodyLength += 4u;
609
        }
610
        bool isStructured = entry.GetMemberTypeDescriptor().isStructuredData;
611
        if (isStructured) {
612
            const ClassRegistryItem *cri = ClassRegistryDatabase::Instance()->Find(memberTypeName);
613
            ok = (cri != NULL_PTR(const ClassRegistryItem*));
614
            for (uint32 h = 0u; h < nElem; h++) {
615
                if (ok) {
616
                    ok = GetBodyLength(cri->GetIntrospection(), bodyLength);
748
    bool OPCUADSInput::GetBodyLength(const Introspection *const intro,
749
                                     uint32 &bodyLength)
750
    {
751
        bool ok = true;
752
        uint32 numberOfMembers = intro->GetNumberOfMembers();
753
        uint32 j;
754
        for (j = 0u; j < numberOfMembers; j++)
755
        {
756
            const IntrospectionEntry entry = intro->operator[](j);
757
            const char8 *const memberTypeName = entry.GetMemberTypeName();
758
            uint32 nElem;
759
            nElem = entry.GetNumberOfElements(0u);
760
            if (nElem > 1u)
761
            {
762
                bodyLength += 4u;
763
            }
764
            bool isStructured = entry.GetMemberTypeDescriptor().isStructuredData;
765
            if (isStructured)
766
            {
767
                const ClassRegistryItem *cri = ClassRegistryDatabase::Instance()->Find(memberTypeName);
768
                ok = (cri != NULL_PTR(const ClassRegistryItem *));
769
                for (uint32 h = 0u; h < nElem; h++)
770
                {
771
                    if (ok)
772
                    {
773
                        ok = GetBodyLength(cri->GetIntrospection(), bodyLength);
774
                    }
617 775
                }
618 776
            }
777
            else
778
            {
779
                uint32 nOfBytes = entry.GetMemberTypeDescriptor().numberOfBits;
780
                nOfBytes /= 8u;
781
                nOfBytes *= nElem;
782
                bodyLength = bodyLength + nOfBytes;
783
            }
619 784
        }
620
        else {
621
            uint32 nOfBytes = entry.GetMemberTypeDescriptor().numberOfBits;
622
            nOfBytes /= 8u;
623
            nOfBytes *= nElem;
624
            bodyLength = bodyLength + nOfBytes;
625
        }
785
        return ok;
626 786
    }
627
    return ok;
628
}
629 787

  
630
void OPCUADSInput::GetStructureDimensions(const Introspection *const intro,
631
                                          uint32 &arraySize) {
632
    bool ok = true;
633
    uint32 numberOfMembers = intro->GetNumberOfMembers();
634

  
635
    for (uint32 j = 0u; j < numberOfMembers; j++) {
636
        arraySize++;
637
        const IntrospectionEntry entry = intro->operator[](j);
638
        const char8 *const memberTypeName = entry.GetMemberTypeName();
639
        bool isStructured = entry.GetMemberTypeDescriptor().isStructuredData;
640
        if (isStructured) {
641
            const ClassRegistryItem *cri = ClassRegistryDatabase::Instance()->Find(memberTypeName);
642
            ok = (cri != NULL_PTR(const ClassRegistryItem*));
643
            if (ok) {
644
                GetStructureDimensions(cri->GetIntrospection(), arraySize);
788
    void OPCUADSInput::GetStructureDimensions(const Introspection *const intro,
789
                                              uint32 &arraySize)
790
    {
791
        bool ok = true;
792
        uint32 numberOfMembers = intro->GetNumberOfMembers();
793

  
794
        for (uint32 j = 0u; j < numberOfMembers; j++)
795
        {
796
            arraySize++;
797
            const IntrospectionEntry entry = intro->operator[](j);
798
            const char8 *const memberTypeName = entry.GetMemberTypeName();
799
            bool isStructured = entry.GetMemberTypeDescriptor().isStructuredData;
800
            if (isStructured)
801
            {
802
                const ClassRegistryItem *cri = ClassRegistryDatabase::Instance()->Find(memberTypeName);
803
                ok = (cri != NULL_PTR(const ClassRegistryItem *));
804
                if (ok)
805
                {
806
                    GetStructureDimensions(cri->GetIntrospection(), arraySize);
807
                }
645 808
            }
646 809
        }
647 810
    }
648
}
649 811

  
650
bool OPCUADSInput::GetStructure(const Introspection * const intro,
651
                                uint32 *&entryArrayElements,
652
                                TypeDescriptor *&entryTypes,
653
                                uint32 *&entryNumberOfMembers,
654
                                uint32 &index) {
655
    bool ok = true;
656
    uint32 numberOfMembers = intro->GetNumberOfMembers();
657

  
658
    uint32 j;
659
    for (j = 0u; j < numberOfMembers; j++) {
660
        const IntrospectionEntry entry = intro->operator[](j);
661

  
662
        /* Updating entryArrayElements */
663
        entryArrayElements[index] = entry.GetNumberOfElements(0u);
664

  
665
        /* Updating entryTypes */
666
        entryTypes[index] = entry.GetMemberTypeDescriptor();
667

  
668
        const char8 *const memberTypeName = entry.GetMemberTypeName();
669
        uint32 nMembers = 1u;
670
        bool isStructured = entry.GetMemberTypeDescriptor().isStructuredData;
671
        if (isStructured) {
672
            const ClassRegistryItem *cri = ClassRegistryDatabase::Instance()->Find(memberTypeName);
673
            ok = (cri != NULL_PTR(const ClassRegistryItem*));
674
            nMembers = cri->GetIntrospection()->GetNumberOfMembers();
675
            /* Updating entryNumberOfMembers */
676
            entryNumberOfMembers[index] = nMembers;
677
            index = index + 1u;
678

  
679
            if (ok) {
680
                ok = GetStructure(cri->GetIntrospection(), entryArrayElements, entryTypes, entryNumberOfMembers, index);
812
    bool OPCUADSInput::GetStructure(const Introspection *const intro,
813
                                    uint32 *&entryArrayElements,
814
                                    TypeDescriptor *&entryTypes,
815
                                    uint32 *&entryNumberOfMembers,
816
                                    uint32 &index)
817
    {
818
        bool ok = true;
819
        uint32 numberOfMembers = intro->GetNumberOfMembers();
820

  
821
        uint32 j;
822
        for (j = 0u; j < numberOfMembers; j++)
823
        {
824
            const IntrospectionEntry entry = intro->operator[](j);
825

  
826
            /* Updating entryArrayElements */
827
            entryArrayElements[index] = entry.GetNumberOfElements(0u);
828

  
829
            /* Updating entryTypes */
830
            entryTypes[index] = entry.GetMemberTypeDescriptor();
831

  
832
            const char8 *const memberTypeName = entry.GetMemberTypeName();
833
            uint32 nMembers = 1u;
834
            bool isStructured = entry.GetMemberTypeDescriptor().isStructuredData;
835
            if (isStructured)
836
            {
837
                const ClassRegistryItem *cri = ClassRegistryDatabase::Instance()->Find(memberTypeName);
838
                ok = (cri != NULL_PTR(const ClassRegistryItem *));
839
                nMembers = cri->GetIntrospection()->GetNumberOfMembers();
840
                /* Updating entryNumberOfMembers */
841
                entryNumberOfMembers[index] = nMembers;
842
                index = index + 1u;
843

  
844
                if (ok)
845
                {
846
                    ok = GetStructure(cri->GetIntrospection(), entryArrayElements, entryTypes, entryNumberOfMembers, index);
847
                }
848
            }
849
            else
850
            {
851
                /* Updating entryNumberOfMembers */
852
                entryNumberOfMembers[index] = nMembers;
853
                index = index + 1u;
681 854
            }
682 855
        }
683
        else {
684
            /* Updating entryNumberOfMembers */
685
            entryNumberOfMembers[index] = nMembers;
686
            index = index + 1u;
687
        }
856
        return ok;
688 857
    }
689
    return ok;
690
}
691 858

  
692
OPCUAClientRead* OPCUADSInput::GetOPCUAClient() {
693
    return masterClient;
694
}
859
    OPCUAClientRead *OPCUADSInput::GetOPCUAClient()
860
    {
861
        return masterClient;
862
    }
695 863

  
696
CLASS_REGISTER(OPCUADSInput, "1.0");
864
    CLASS_REGISTER(OPCUADSInput, "1.0");
697 865

  
698 866
}
699 867
/*lint -restore*/
Source/Components/DataSources/OPCUADataSource/OPCUADSInput.h
114 114
 *             NamespaceIndex = 3
115 115
 *             Path = Object3.Block1.Block2.NodeStructure1
116 116
 *             ExtensionObject = "yes"
117
 *         }
117
 *             SynchSignal = 1 //if Synchronise at least one signal shall specify it
118
 *         }s
118 119
 *     }
119 120
 * }
120 121
 * </pre>
......
378 379
     * 
379 380
     */
380 381
    StreamString password;
382

  
383
  
381 384
};
382 385

  
383 386
}
Source/Components/DataSources/OPCUADataSource/OPCUADSOutput.cpp
487 487

  
488 488
/*lint -e{715}  [MISRA C++ Rule 0-1-11], [MISRA C++ Rule 0-1-12]. Justification: The brokerName only depends on the direction */
489 489
const char8* OPCUADSOutput::GetBrokerName(StructuredDataI &data,
490
                                          const SignalDirection direction) {
491
    const char8 *brokerName = "";
490
                                         const SignalDirection direction) {
491

  
492
    const char8 *brokerName = NULL_PTR(const char8*);
493

  
492 494
    if (direction == OutputSignals) {
493
        brokerName = "MemoryMapSynchronisedOutputBroker";
495

  
496
        uint32 trigger = 0u;
497

  
498
        if (!data.Read("Trigger", trigger)) {
499
            trigger = 0u;
500
        }
501

  
502
        if (trigger == 1u) {
503
            brokerName = "MemoryMapSynchronisedOutputBroker";
504
        
505
        }
506
        else {
507
            brokerName = "MemoryMapOutputBroker";
508
        }
509

  
510
    }
511
    else {
512
        
513
         REPORT_ERROR(ErrorManagement::ParametersError, "DataSource not compatible with InputSignals");
514
        
494 515
    }
516

  
495 517
    return brokerName;
496 518
}
497 519

  
Source/Components/DataSources/OPCUADataSource/OPCUADSOutput.h
87 87
 *             Type = MyStructure
88 88
 *             NamespaceIndex = 3
89 89
 *             Path = Object3.Block1.Block2.NodeStructure1
90
 *             Trigger=1 //at least one Signal shall specify it 
90 91
 *         }
91 92
 *     }
92 93
 * }