Coverage Report

Created: 2025-08-26 06:30

/src/open62541/src/server/ua_server_ns0.c
Line
Count
Source (jump to first uncovered line)
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
 *
5
 *    Copyright 2017-2022 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
6
 *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
7
 *    Copyright 2017 (c) Thomas Bender
8
 *    Copyright 2017 (c) Julian Grothoff
9
 *    Copyright 2017 (c) Henrik Norrman
10
 *    Copyright 2018 (c) Fabian Arndt, Root-Core
11
 *    Copyright 2019 (c) Kalycito Infotech Private Limited
12
 *    Copyright 2021 (c) Christian von Arnim, ISW University of Stuttgart (for VDW and umati)
13
 *    Copyright 2023 (c) Fraunhofer IOSB (Author: Andreas Ebner)
14
 */
15
16
#include "open62541/namespace0_generated.h"
17
18
#include "ua_server_internal.h"
19
#include "ua_session.h"
20
#include "ua_subscription.h"
21
22
static UA_StatusCode
23
ns0_addNode_raw(UA_Server *server, UA_NodeClass nodeClass,
24
            UA_UInt32 nodeId, char *name, void *attributes,
25
3.30k
            const UA_DataType *attributesType) {
26
3.30k
    UA_AddNodesItem item;
27
3.30k
    UA_AddNodesItem_init(&item);
28
3.30k
    item.nodeClass = nodeClass;
29
3.30k
    item.requestedNewNodeId.nodeId = UA_NODEID_NUMERIC(0, nodeId);
30
3.30k
    item.browseName = UA_QUALIFIEDNAME(0, name);
31
3.30k
    UA_ExtensionObject_setValueNoDelete(&item.nodeAttributes,
32
3.30k
                                        attributes, attributesType);
33
3.30k
    return addNode_raw(server, &server->adminSession, NULL, &item, NULL);
34
3.30k
}
35
36
static UA_StatusCode
37
ns0_addNode_finish(UA_Server *server, UA_UInt32 nodeId,
38
3.30k
               UA_UInt32 parentNodeId, UA_UInt32 referenceTypeId) {
39
3.30k
    const UA_NodeId sourceId = UA_NODEID_NUMERIC(0, nodeId);
40
3.30k
    const UA_NodeId refTypeId = UA_NODEID_NUMERIC(0, referenceTypeId);
41
3.30k
    const UA_NodeId targetId = UA_NODEID_NUMERIC(0, parentNodeId);
42
3.30k
    UA_StatusCode retval = addRef(server, sourceId, refTypeId, targetId, false);
43
3.30k
    if(retval != UA_STATUSCODE_GOOD)
44
0
        return retval;
45
3.30k
    return addNode_finish(server, &server->adminSession, &sourceId);
46
3.30k
}
47
48
static UA_StatusCode
49
addObjectNode(UA_Server *server, char* name, UA_UInt32 objectid,
50
4.95k
              UA_UInt32 parentid, UA_UInt32 referenceid, UA_UInt32 type_id) {
51
4.95k
    UA_ObjectAttributes object_attr = UA_ObjectAttributes_default;
52
4.95k
    object_attr.displayName = UA_LOCALIZEDTEXT("", name);
53
4.95k
    return addNode(server, UA_NODECLASS_OBJECT, UA_NODEID_NUMERIC(0, objectid),
54
4.95k
                   UA_NODEID_NUMERIC(0, parentid), UA_NODEID_NUMERIC(0, referenceid),
55
4.95k
                   UA_QUALIFIEDNAME(0, name), UA_NODEID_NUMERIC(0, type_id),
56
4.95k
                   &object_attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
57
4.95k
                   NULL, NULL);
58
4.95k
}
59
60
static UA_StatusCode
61
addReferenceTypeNode(UA_Server *server, char* name, char *inverseName, UA_UInt32 referencetypeid,
62
8.26k
                     UA_Boolean isabstract, UA_Boolean symmetric, UA_UInt32 parentid) {
63
8.26k
    UA_ReferenceTypeAttributes reference_attr = UA_ReferenceTypeAttributes_default;
64
8.26k
    reference_attr.displayName = UA_LOCALIZEDTEXT("", name);
65
8.26k
    reference_attr.isAbstract = isabstract;
66
8.26k
    reference_attr.symmetric = symmetric;
67
8.26k
    if(inverseName)
68
6.61k
        reference_attr.inverseName = UA_LOCALIZEDTEXT("", inverseName);
69
8.26k
    return addNode(server, UA_NODECLASS_REFERENCETYPE, UA_NODEID_NUMERIC(0, referencetypeid),
70
8.26k
                   UA_NODEID_NUMERIC(0, parentid), UA_NODEID_NULL, UA_QUALIFIEDNAME(0, name),
71
8.26k
                   UA_NODEID_NULL, &reference_attr,
72
8.26k
                   &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES], NULL, NULL);
73
8.26k
}
74
75
/***************************/
76
/* Bootstrap NS0 hierarchy */
77
/***************************/
78
79
/* Creates the basic nodes which are expected by the nodeset compiler to be
80
 * already created. This is necessary to reduce the dependencies for the nodeset
81
 * compiler. */
82
static UA_StatusCode
83
551
createNS0_base(UA_Server *server) {
84
    /* Bootstrap ReferenceTypes. The order of these is important for the
85
     * ReferenceTypeIndex. The ReferenceTypeIndex is created with the raw node.
86
     * The ReferenceTypeSet of subtypes for every ReferenceType is created
87
     * during the call to AddNode_finish. */
88
551
    UA_StatusCode ret = UA_STATUSCODE_GOOD;
89
551
    UA_ReferenceTypeAttributes references_attr = UA_ReferenceTypeAttributes_default;
90
551
    references_attr.displayName = UA_LOCALIZEDTEXT("", "References");
91
551
    references_attr.isAbstract = true;
92
551
    references_attr.symmetric = true;
93
551
    references_attr.inverseName = UA_LOCALIZEDTEXT("", "References");
94
551
    ret |= ns0_addNode_raw(server, UA_NODECLASS_REFERENCETYPE, UA_NS0ID_REFERENCES, "References",
95
551
                           &references_attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]);
96
97
551
    UA_ReferenceTypeAttributes hassubtype_attr = UA_ReferenceTypeAttributes_default;
98
551
    hassubtype_attr.displayName = UA_LOCALIZEDTEXT("", "HasSubtype");
99
551
    hassubtype_attr.isAbstract = false;
100
551
    hassubtype_attr.symmetric = false;
101
551
    hassubtype_attr.inverseName = UA_LOCALIZEDTEXT("", "SubtypeOf");
102
551
    ret |= ns0_addNode_raw(server, UA_NODECLASS_REFERENCETYPE, UA_NS0ID_HASSUBTYPE, "HasSubtype",
103
551
                           &hassubtype_attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]);
104
105
551
    UA_ReferenceTypeAttributes aggregates_attr = UA_ReferenceTypeAttributes_default;
106
551
    aggregates_attr.displayName = UA_LOCALIZEDTEXT("", "Aggregates");
107
551
    aggregates_attr.isAbstract = true;
108
551
    aggregates_attr.symmetric = false;
109
551
    aggregates_attr.inverseName = UA_LOCALIZEDTEXT("", "AggregatedBy");
110
551
    ret |= ns0_addNode_raw(server, UA_NODECLASS_REFERENCETYPE, UA_NS0ID_AGGREGATES, "Aggregates",
111
551
                           &aggregates_attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]);
112
113
551
    ret |= addReferenceTypeNode(server, "HierarchicalReferences", NULL,
114
551
                         UA_NS0ID_HIERARCHICALREFERENCES, true, false, UA_NS0ID_REFERENCES);
115
116
551
    ret |= addReferenceTypeNode(server, "NonHierarchicalReferences", NULL,
117
551
                         UA_NS0ID_NONHIERARCHICALREFERENCES, true, true, UA_NS0ID_REFERENCES);
118
119
551
    ret |= addReferenceTypeNode(server, "HasChild", NULL, UA_NS0ID_HASCHILD,
120
551
                         true, false, UA_NS0ID_HIERARCHICALREFERENCES);
121
122
551
    ret |= addReferenceTypeNode(server, "Organizes", "OrganizedBy", UA_NS0ID_ORGANIZES,
123
551
                         false, false, UA_NS0ID_HIERARCHICALREFERENCES);
124
125
551
    ret |= addReferenceTypeNode(server, "HasEventSource", "EventSourceOf", UA_NS0ID_HASEVENTSOURCE,
126
551
                         false, false, UA_NS0ID_HIERARCHICALREFERENCES);
127
128
551
    ret |= addReferenceTypeNode(server, "HasModellingRule", "ModellingRuleOf", UA_NS0ID_HASMODELLINGRULE,
129
551
                         false, false, UA_NS0ID_NONHIERARCHICALREFERENCES);
130
131
551
    ret |= addReferenceTypeNode(server, "HasEncoding", "EncodingOf", UA_NS0ID_HASENCODING,
132
551
                         false, false, UA_NS0ID_NONHIERARCHICALREFERENCES);
133
134
551
    ret |= addReferenceTypeNode(server, "HasDescription", "DescriptionOf", UA_NS0ID_HASDESCRIPTION,
135
551
                         false, false, UA_NS0ID_NONHIERARCHICALREFERENCES);
136
137
551
    ret |= addReferenceTypeNode(server, "HasTypeDefinition", "TypeDefinitionOf", UA_NS0ID_HASTYPEDEFINITION,
138
551
                         false, false, UA_NS0ID_NONHIERARCHICALREFERENCES);
139
140
551
    ret |= addReferenceTypeNode(server, "GeneratesEvent", "GeneratedBy", UA_NS0ID_GENERATESEVENT,
141
551
                         false, false, UA_NS0ID_NONHIERARCHICALREFERENCES);
142
143
    /* Complete bootstrap of Aggregates */
144
551
    ret |= ns0_addNode_finish(server, UA_NS0ID_AGGREGATES, UA_NS0ID_HASCHILD, UA_NS0ID_HASSUBTYPE);
145
146
    /* Complete bootstrap of HasSubtype */
147
551
    ret |= ns0_addNode_finish(server, UA_NS0ID_HASSUBTYPE, UA_NS0ID_HASCHILD, UA_NS0ID_HASSUBTYPE);
148
149
551
    ret |= addReferenceTypeNode(server, "HasProperty", "PropertyOf", UA_NS0ID_HASPROPERTY,
150
551
                         false, false, UA_NS0ID_AGGREGATES);
151
152
551
    ret |= addReferenceTypeNode(server, "HasComponent", "ComponentOf", UA_NS0ID_HASCOMPONENT,
153
551
                         false, false, UA_NS0ID_AGGREGATES);
154
155
551
    ret |= addReferenceTypeNode(server, "HasNotifier", "NotifierOf", UA_NS0ID_HASNOTIFIER,
156
551
                         false, false, UA_NS0ID_HASEVENTSOURCE);
157
158
551
    ret |= addReferenceTypeNode(server, "HasOrderedComponent", "OrderedComponentOf",
159
551
                         UA_NS0ID_HASORDEREDCOMPONENT, false, false, UA_NS0ID_HASCOMPONENT);
160
161
551
    ret |= addReferenceTypeNode(server, "HasInterface", "InterfaceOf",
162
551
                         UA_NS0ID_HASINTERFACE, false, false, UA_NS0ID_NONHIERARCHICALREFERENCES);
163
164
    /**************/
165
    /* Data Types */
166
    /**************/
167
168
    /* Bootstrap BaseDataType */
169
551
    UA_DataTypeAttributes basedatatype_attr = UA_DataTypeAttributes_default;
170
551
    basedatatype_attr.displayName = UA_LOCALIZEDTEXT("", "BaseDataType");
171
551
    basedatatype_attr.isAbstract = true;
172
551
    ret |= ns0_addNode_raw(server, UA_NODECLASS_DATATYPE, UA_NS0ID_BASEDATATYPE, "BaseDataType",
173
551
                           &basedatatype_attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES]);
174
175
    /*****************/
176
    /* VariableTypes */
177
    /*****************/
178
179
551
    UA_VariableTypeAttributes basevar_attr = UA_VariableTypeAttributes_default;
180
551
    basevar_attr.displayName = UA_LOCALIZEDTEXT("", "BaseVariableType");
181
551
    basevar_attr.isAbstract = true;
182
551
    basevar_attr.valueRank = UA_VALUERANK_ANY;
183
551
    basevar_attr.dataType = UA_NS0ID(BASEDATATYPE);
184
551
    ret |= ns0_addNode_raw(server, UA_NODECLASS_VARIABLETYPE,
185
551
                           UA_NS0ID_BASEVARIABLETYPE, "BaseVariableType",
186
551
                           &basevar_attr, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES]);
187
188
551
    UA_VariableTypeAttributes bdv_attr = UA_VariableTypeAttributes_default;
189
551
    bdv_attr.displayName = UA_LOCALIZEDTEXT("", "BaseDataVariableType");
190
551
    bdv_attr.dataType = UA_NS0ID(BASEDATATYPE);
191
551
    bdv_attr.valueRank = UA_VALUERANK_ANY;
192
551
    ret |= addNode(server, UA_NODECLASS_VARIABLETYPE,
193
551
                   UA_NS0ID(BASEDATAVARIABLETYPE), UA_NS0ID(BASEVARIABLETYPE),
194
551
                   UA_NODEID_NULL, UA_QUALIFIEDNAME(0, "BaseDataVariableType"),
195
551
                   UA_NODEID_NULL, &bdv_attr, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],
196
551
                   NULL, NULL);
197
198
551
    UA_VariableTypeAttributes prop_attr = UA_VariableTypeAttributes_default;
199
551
    prop_attr.displayName = UA_LOCALIZEDTEXT("", "PropertyType");
200
551
    prop_attr.dataType = UA_NS0ID(BASEDATATYPE);
201
551
    prop_attr.valueRank = UA_VALUERANK_ANY;
202
551
    ret |= addNode(server, UA_NODECLASS_VARIABLETYPE,
203
551
                   UA_NS0ID(PROPERTYTYPE), UA_NS0ID(BASEVARIABLETYPE),
204
551
                   UA_NODEID_NULL, UA_QUALIFIEDNAME(0, "PropertyType"),
205
551
                   UA_NODEID_NULL, &prop_attr,
206
551
                   &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES], NULL, NULL);
207
208
    /***************/
209
    /* ObjectTypes */
210
    /***************/
211
212
551
    UA_ObjectTypeAttributes baseobj_attr = UA_ObjectTypeAttributes_default;
213
551
    baseobj_attr.displayName = UA_LOCALIZEDTEXT("", "BaseObjectType");
214
551
    ret |= ns0_addNode_raw(server, UA_NODECLASS_OBJECTTYPE,
215
551
                           UA_NS0ID_BASEOBJECTTYPE, "BaseObjectType",
216
551
                           &baseobj_attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES]);
217
218
551
    UA_ObjectTypeAttributes folder_attr = UA_ObjectTypeAttributes_default;
219
551
    folder_attr.displayName = UA_LOCALIZEDTEXT("", "FolderType");
220
551
    ret |= addNode(server, UA_NODECLASS_OBJECTTYPE,
221
551
                   UA_NS0ID(FOLDERTYPE), UA_NS0ID(BASEOBJECTTYPE),
222
551
                   UA_NODEID_NULL, UA_QUALIFIEDNAME(0, "FolderType"),
223
551
                   UA_NODEID_NULL,
224
551
                   &folder_attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES], NULL, NULL);
225
226
    /******************/
227
    /* Root and below */
228
    /******************/
229
230
551
    ret |= addObjectNode(server, "Root", UA_NS0ID_ROOTFOLDER, 0, 0, UA_NS0ID_FOLDERTYPE);
231
232
551
    ret |= addObjectNode(server, "Objects", UA_NS0ID_OBJECTSFOLDER, UA_NS0ID_ROOTFOLDER,
233
551
                  UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE);
234
235
551
    ret |= addObjectNode(server, "Types", UA_NS0ID_TYPESFOLDER, UA_NS0ID_ROOTFOLDER,
236
551
                  UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE);
237
238
551
    ret |= addObjectNode(server, "ReferenceTypes", UA_NS0ID_REFERENCETYPESFOLDER, UA_NS0ID_TYPESFOLDER,
239
551
                  UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE);
240
551
    ret |= ns0_addNode_finish(server, UA_NS0ID_REFERENCES,
241
551
                              UA_NS0ID_REFERENCETYPESFOLDER, UA_NS0ID_ORGANIZES);
242
243
551
    ret |= addObjectNode(server, "DataTypes", UA_NS0ID_DATATYPESFOLDER, UA_NS0ID_TYPESFOLDER,
244
551
                  UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE);
245
551
    ret |= ns0_addNode_finish(server, UA_NS0ID_BASEDATATYPE,
246
551
                              UA_NS0ID_DATATYPESFOLDER, UA_NS0ID_ORGANIZES);
247
248
551
    ret |= addObjectNode(server, "VariableTypes", UA_NS0ID_VARIABLETYPESFOLDER, UA_NS0ID_TYPESFOLDER,
249
551
                  UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE);
250
551
    ret |= ns0_addNode_finish(server, UA_NS0ID_BASEVARIABLETYPE,
251
551
                              UA_NS0ID_VARIABLETYPESFOLDER, UA_NS0ID_ORGANIZES);
252
253
551
    ret |= addObjectNode(server, "ObjectTypes", UA_NS0ID_OBJECTTYPESFOLDER, UA_NS0ID_TYPESFOLDER,
254
551
                  UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE);
255
551
    ret |= ns0_addNode_finish(server, UA_NS0ID_BASEOBJECTTYPE,
256
551
                              UA_NS0ID_OBJECTTYPESFOLDER, UA_NS0ID_ORGANIZES);
257
258
551
    ret |= addObjectNode(server, "EventTypes", UA_NS0ID_EVENTTYPESFOLDER, UA_NS0ID_TYPESFOLDER,
259
551
                  UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE);
260
261
551
    ret |= addObjectNode(server, "Views", UA_NS0ID_VIEWSFOLDER, UA_NS0ID_ROOTFOLDER,
262
551
                  UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE);
263
264
    /* Add BaseEventType */
265
551
    UA_ObjectTypeAttributes eventtype_attr = UA_ObjectTypeAttributes_default;
266
551
    eventtype_attr.displayName = UA_LOCALIZEDTEXT("", "BaseEventType");
267
551
    ret |= addNode(server, UA_NODECLASS_OBJECTTYPE, UA_NS0ID(BASEEVENTTYPE),
268
551
                   UA_NS0ID(BASEOBJECTTYPE), UA_NODEID_NULL,
269
551
                   UA_QUALIFIEDNAME(0, "BaseEventType"), UA_NODEID_NULL, &eventtype_attr,
270
551
                   &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES], NULL, NULL);
271
551
    ret |= addRef(server, UA_NS0ID(EVENTTYPESFOLDER), UA_NS0ID(ORGANIZES),
272
551
                  UA_NS0ID(BASEEVENTTYPE), true);
273
274
551
    if(ret != UA_STATUSCODE_GOOD)
275
0
        ret = UA_STATUSCODE_BADINTERNALERROR;
276
277
551
    return ret;
278
551
}
279
280
/****************/
281
/* Data Sources */
282
/****************/
283
284
static UA_StatusCode
285
writeStatus(UA_Server *server, const UA_NodeId *sessionId,
286
            void *sessionContext, const UA_NodeId *nodeId,
287
            void *nodeContext, const UA_NumericRange *range,
288
0
            const UA_DataValue *value) {
289
0
    if(range)
290
0
        return UA_STATUSCODE_BADINDEXRANGEINVALID;
291
292
0
    if(nodeId->identifier.numeric != UA_NS0ID_SERVER_SERVERSTATUS_SECONDSTILLSHUTDOWN)
293
0
        return UA_STATUSCODE_BADINTERNALERROR;
294
295
    /* Only the local user can write into this variable */
296
0
    if(sessionId != &server->adminSession.sessionId)
297
0
        return UA_STATUSCODE_BADUSERACCESSDENIED;
298
299
0
    if(!UA_Variant_hasScalarType(&value->value, &UA_TYPES[UA_TYPES_UINT32]))
300
0
        return UA_STATUSCODE_BADTYPEMISMATCH;
301
302
0
    UA_EventLoop *el = server->config.eventLoop;
303
0
    UA_UInt32 *endTime = (UA_UInt32*)value->value.data;
304
0
    server->endTime = el->dateTime_now(el) + (UA_DateTime)(*endTime * UA_DATETIME_SEC);
305
0
    return UA_STATUSCODE_GOOD;
306
0
}
307
308
static UA_StatusCode
309
readStatus(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
310
           const UA_NodeId *nodeId, void *nodeContext, UA_Boolean sourceTimestamp,
311
0
           const UA_NumericRange *range, UA_DataValue *value) {
312
0
    UA_EventLoop *el = server->config.eventLoop;
313
314
0
    if(range) {
315
0
        value->hasStatus = true;
316
0
        value->status = UA_STATUSCODE_BADINDEXRANGEINVALID;
317
0
        return UA_STATUSCODE_GOOD;
318
0
    }
319
320
0
    if(sourceTimestamp) {
321
0
        value->hasSourceTimestamp = true;
322
0
        value->sourceTimestamp = el->dateTime_now(el);
323
0
    }
324
325
0
    void *data = NULL;
326
327
0
    UA_assert(nodeId->identifierType == UA_NODEIDTYPE_NUMERIC);
328
329
0
    switch(nodeId->identifier.numeric) {
330
0
    case UA_NS0ID_SERVER_SERVERSTATUS_SECONDSTILLSHUTDOWN: {
331
0
        UA_UInt32 *shutdown = UA_UInt32_new();
332
0
        if(!shutdown)
333
0
            return UA_STATUSCODE_BADOUTOFMEMORY;
334
0
        if(server->endTime != 0)
335
0
            *shutdown = (UA_UInt32)((server->endTime - el->dateTime_now(el)) / UA_DATETIME_SEC);
336
0
        value->value.data = shutdown;
337
0
        value->value.type = &UA_TYPES[UA_TYPES_UINT32];
338
0
        value->hasValue = true;
339
0
        return UA_STATUSCODE_GOOD;
340
0
    }
341
342
0
    case UA_NS0ID_SERVER_SERVERSTATUS_STATE: {
343
0
        UA_ServerState *state = UA_ServerState_new();
344
0
        if(!state)
345
0
            return UA_STATUSCODE_BADOUTOFMEMORY;
346
0
        if(server->endTime != 0)
347
0
            *state = UA_SERVERSTATE_SHUTDOWN;
348
0
        value->value.data = state;
349
0
        value->value.type = &UA_TYPES[UA_TYPES_SERVERSTATE];
350
0
        value->hasValue = true;
351
0
        return UA_STATUSCODE_GOOD;
352
0
    }
353
354
0
    case UA_NS0ID_SERVER_SERVERSTATUS: {
355
0
        UA_ServerStatusDataType *statustype = UA_ServerStatusDataType_new();
356
0
        if(!statustype)
357
0
            return UA_STATUSCODE_BADOUTOFMEMORY;
358
0
        statustype->startTime = server->startTime;
359
0
        statustype->currentTime = el->dateTime_now(el);
360
361
0
        statustype->state = UA_SERVERSTATE_RUNNING;
362
0
        statustype->secondsTillShutdown = 0;
363
0
        if(server->endTime != 0) {
364
0
            statustype->state = UA_SERVERSTATE_SHUTDOWN;
365
0
            statustype->secondsTillShutdown = (UA_UInt32)
366
0
                ((server->endTime - el->dateTime_now(el)) / UA_DATETIME_SEC);
367
0
        }
368
369
0
        value->value.data = statustype;
370
0
        value->value.type = &UA_TYPES[UA_TYPES_SERVERSTATUSDATATYPE];
371
0
        value->hasValue = true;
372
0
        return UA_BuildInfo_copy(&server->config.buildInfo, &statustype->buildInfo);
373
0
    }
374
375
0
    case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO:
376
0
        value->value.type = &UA_TYPES[UA_TYPES_BUILDINFO];
377
0
        data = &server->config.buildInfo;
378
0
        break;
379
380
0
    case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTURI:
381
0
        value->value.type = &UA_TYPES[UA_TYPES_STRING];
382
0
        data = &server->config.buildInfo.productUri;
383
0
        break;
384
385
0
    case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_MANUFACTURERNAME:
386
0
        value->value.type = &UA_TYPES[UA_TYPES_STRING];
387
0
        data = &server->config.buildInfo.manufacturerName;
388
0
        break;
389
390
0
    case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTNAME:
391
0
        value->value.type = &UA_TYPES[UA_TYPES_STRING];
392
0
        data = &server->config.buildInfo.productName;
393
0
        break;
394
395
0
    case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_SOFTWAREVERSION:
396
0
        value->value.type = &UA_TYPES[UA_TYPES_STRING];
397
0
        data = &server->config.buildInfo.softwareVersion;
398
0
        break;
399
400
0
    case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDNUMBER:
401
0
        value->value.type = &UA_TYPES[UA_TYPES_STRING];
402
0
        data = &server->config.buildInfo.buildNumber;
403
0
        break;
404
405
0
    case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDDATE:
406
0
        value->value.type = &UA_TYPES[UA_TYPES_DATETIME];
407
0
        data = &server->config.buildInfo.buildDate;
408
0
        break;
409
410
0
    default:
411
0
        value->hasStatus = true;
412
0
        value->status = UA_STATUSCODE_BADINTERNALERROR;
413
0
        return UA_STATUSCODE_GOOD;
414
0
    }
415
416
0
    value->value.data = UA_new(value->value.type);
417
0
    if(!value->value.data) {
418
0
        value->value.type = NULL;
419
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
420
0
    }
421
422
0
    value->hasValue = true;
423
0
    return UA_copy(data, value->value.data, value->value.type);
424
0
}
425
426
#ifdef UA_GENERATED_NAMESPACE_ZERO
427
static UA_StatusCode
428
readServiceLevel(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
429
                 const UA_NodeId *nodeId, void *nodeContext, UA_Boolean includeSourceTimeStamp,
430
0
                 const UA_NumericRange *range, UA_DataValue *value) {
431
0
    UA_EventLoop *el = server->config.eventLoop;
432
433
0
    if(range) {
434
0
        value->hasStatus = true;
435
0
        value->status = UA_STATUSCODE_BADINDEXRANGEINVALID;
436
0
        return UA_STATUSCODE_GOOD;
437
0
    }
438
439
0
    value->value.type = &UA_TYPES[UA_TYPES_BYTE];
440
0
    value->value.arrayLength = 0;
441
0
    UA_Byte *byte = UA_Byte_new();
442
0
    if(!byte)
443
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
444
0
    *byte = 255;
445
0
    value->value.data = byte;
446
0
    value->value.arrayDimensionsSize = 0;
447
0
    value->value.arrayDimensions = NULL;
448
0
    value->hasValue = true;
449
0
    if(includeSourceTimeStamp) {
450
0
        value->hasSourceTimestamp = true;
451
0
        value->sourceTimestamp = el->dateTime_now(el);
452
0
    }
453
0
    return UA_STATUSCODE_GOOD;
454
0
}
455
456
static UA_StatusCode
457
readAuditing(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
458
             const UA_NodeId *nodeId, void *nodeContext, UA_Boolean includeSourceTimeStamp,
459
0
             const UA_NumericRange *range, UA_DataValue *value) {
460
0
    UA_EventLoop *el = server->config.eventLoop;
461
462
0
    if(range) {
463
0
        value->hasStatus = true;
464
0
        value->status = UA_STATUSCODE_BADINDEXRANGEINVALID;
465
0
        return UA_STATUSCODE_GOOD;
466
0
    }
467
468
0
    value->value.type = &UA_TYPES[UA_TYPES_BOOLEAN];
469
0
    value->value.arrayLength = 0;
470
0
    UA_Boolean *boolean = UA_Boolean_new();
471
0
    if(!boolean)
472
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
473
0
    *boolean = false;
474
0
    value->value.data = boolean;
475
0
    value->value.arrayDimensionsSize = 0;
476
0
    value->value.arrayDimensions = NULL;
477
0
    value->hasValue = true;
478
0
    if(includeSourceTimeStamp) {
479
0
        value->hasSourceTimestamp = true;
480
0
        value->sourceTimestamp = el->dateTime_now(el);
481
0
    }
482
0
    return UA_STATUSCODE_GOOD;
483
0
}
484
#endif
485
486
static UA_StatusCode
487
readNamespaces(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
488
               const UA_NodeId *nodeid, void *nodeContext, UA_Boolean includeSourceTimeStamp,
489
               const UA_NumericRange *range,
490
0
               UA_DataValue *value) {
491
0
    UA_EventLoop *el = server->config.eventLoop;
492
493
    /* ensure that the uri for ns1 is set up from the app description */
494
0
    setupNs1Uri(server);
495
496
0
    if(range) {
497
0
        value->hasStatus = true;
498
0
        value->status = UA_STATUSCODE_BADINDEXRANGEINVALID;
499
0
        return UA_STATUSCODE_GOOD;
500
0
    }
501
0
    UA_StatusCode retval;
502
0
    retval = UA_Variant_setArrayCopy(&value->value, server->namespaces,
503
0
                                     server->namespacesSize, &UA_TYPES[UA_TYPES_STRING]);
504
0
    if(retval != UA_STATUSCODE_GOOD)
505
0
        return retval;
506
0
    value->hasValue = true;
507
0
    if(includeSourceTimeStamp) {
508
0
        value->hasSourceTimestamp = true;
509
0
        value->sourceTimestamp = el->dateTime_now(el);
510
0
    }
511
0
    return UA_STATUSCODE_GOOD;
512
0
}
513
514
static UA_StatusCode
515
writeNamespaces(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
516
                const UA_NodeId *nodeid, void *nodeContext, const UA_NumericRange *range,
517
0
                const UA_DataValue *value) {
518
    /* Check the data type */
519
0
    if(!value->hasValue ||
520
0
       value->value.type != &UA_TYPES[UA_TYPES_STRING])
521
0
        return UA_STATUSCODE_BADTYPEMISMATCH;
522
523
    /* Check that the variant is not empty */
524
0
    if(!value->value.data)
525
0
        return UA_STATUSCODE_BADTYPEMISMATCH;
526
527
    /* TODO: Writing with a range is not implemented */
528
0
    if(range)
529
0
        return UA_STATUSCODE_BADINTERNALERROR;
530
531
0
    UA_String *newNamespaces = (UA_String*)value->value.data;
532
0
    size_t newNamespacesSize = value->value.arrayLength;
533
534
    /* Test if we append to the existing namespaces */
535
0
    if(newNamespacesSize <= server->namespacesSize)
536
0
        return UA_STATUSCODE_BADTYPEMISMATCH;
537
538
    /* ensure that the uri for ns1 is set up from the app description */
539
0
    setupNs1Uri(server);
540
541
    /* Test if the existing namespaces are unchanged */
542
0
    for(size_t i = 0; i < server->namespacesSize; ++i) {
543
0
        if(!UA_String_equal(&server->namespaces[i], &newNamespaces[i]))
544
0
            return UA_STATUSCODE_BADINTERNALERROR;
545
0
    }
546
547
    /* Add namespaces */
548
0
    for(size_t i = server->namespacesSize; i < newNamespacesSize; ++i)
549
0
        addNamespace(server, newNamespaces[i]);
550
0
    return UA_STATUSCODE_GOOD;
551
0
}
552
553
static UA_StatusCode
554
readCurrentTime(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
555
                const UA_NodeId *nodeid, void *nodeContext, UA_Boolean sourceTimeStamp,
556
0
                const UA_NumericRange *range, UA_DataValue *value) {
557
0
    UA_EventLoop *el = server->config.eventLoop;
558
559
0
    if(range) {
560
0
        value->hasStatus = true;
561
0
        value->status = UA_STATUSCODE_BADINDEXRANGEINVALID;
562
0
        return UA_STATUSCODE_GOOD;
563
0
    }
564
565
0
    UA_DateTime currentTime = el->dateTime_now(el);
566
0
    UA_StatusCode retval = UA_Variant_setScalarCopy(&value->value, &currentTime,
567
0
                                                    &UA_TYPES[UA_TYPES_DATETIME]);
568
0
    if(retval != UA_STATUSCODE_GOOD)
569
0
        return retval;
570
0
    value->hasValue = true;
571
0
    if(sourceTimeStamp) {
572
0
        value->hasSourceTimestamp = true;
573
0
        value->sourceTimestamp = currentTime;
574
0
    }
575
0
    return UA_STATUSCODE_GOOD;
576
0
}
577
578
#ifdef UA_GENERATED_NAMESPACE_ZERO
579
static UA_StatusCode
580
readOperationLimits(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
581
                        const UA_NodeId *nodeid, void *nodeContext, UA_Boolean includeSourceTimeStamp,
582
                        const UA_NumericRange *range,
583
0
                        UA_DataValue *value) {
584
0
    UA_StatusCode retval = UA_STATUSCODE_GOOD;
585
0
    if(nodeid->identifierType != UA_NODEIDTYPE_NUMERIC)
586
0
        return UA_STATUSCODE_BADNOTSUPPORTED;
587
0
    switch(nodeid->identifier.numeric) {
588
0
        case UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERREAD:
589
0
            retval = UA_Variant_setScalarCopy(&value->value, &server->config.maxNodesPerRead, &UA_TYPES[UA_TYPES_UINT32]);
590
0
            break;
591
0
        case UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERWRITE:
592
0
            retval = UA_Variant_setScalarCopy(&value->value, &server->config.maxNodesPerWrite, &UA_TYPES[UA_TYPES_UINT32]);
593
0
            break;
594
0
        case UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERMETHODCALL:
595
0
            retval = UA_Variant_setScalarCopy(&value->value, &server->config.maxNodesPerMethodCall, &UA_TYPES[UA_TYPES_UINT32]);
596
0
            break;
597
0
        case UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERBROWSE:
598
0
            retval = UA_Variant_setScalarCopy(&value->value, &server->config.maxNodesPerBrowse, &UA_TYPES[UA_TYPES_UINT32]);
599
0
            break;
600
0
        case UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERREGISTERNODES:
601
0
            retval = UA_Variant_setScalarCopy(&value->value, &server->config.maxNodesPerRegisterNodes, &UA_TYPES[UA_TYPES_UINT32]);
602
0
            break;
603
0
        case UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERTRANSLATEBROWSEPATHSTONODEIDS:
604
0
            retval = UA_Variant_setScalarCopy(&value->value, &server->config.maxNodesPerTranslateBrowsePathsToNodeIds, &UA_TYPES[UA_TYPES_UINT32]);
605
0
            break;
606
0
        case UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERNODEMANAGEMENT:
607
0
            retval = UA_Variant_setScalarCopy(&value->value, &server->config.maxNodesPerNodeManagement, &UA_TYPES[UA_TYPES_UINT32]);
608
0
            break;
609
0
        case UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXMONITOREDITEMSPERCALL:
610
0
            retval = UA_Variant_setScalarCopy(&value->value, &server->config.maxMonitoredItemsPerCall, &UA_TYPES[UA_TYPES_UINT32]);
611
0
            break;
612
0
        default:
613
0
            retval = UA_STATUSCODE_BADNOTSUPPORTED;
614
0
    }
615
0
    return retval;
616
0
}
617
618
static UA_StatusCode
619
readMinSamplingInterval(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
620
               const UA_NodeId *nodeid, void *nodeContext, UA_Boolean includeSourceTimeStamp,
621
0
               const UA_NumericRange *range, UA_DataValue *value) {
622
0
    UA_EventLoop *el = server->config.eventLoop;
623
624
0
    if(range) {
625
0
        value->hasStatus = true;
626
0
        value->status = UA_STATUSCODE_BADINDEXRANGEINVALID;
627
0
        return UA_STATUSCODE_GOOD;
628
0
    }
629
630
0
    UA_StatusCode retval;
631
0
    UA_Duration minInterval;
632
0
#ifdef UA_ENABLE_SUBSCRIPTIONS
633
0
    minInterval = server->config.samplingIntervalLimits.min;
634
#else
635
    minInterval = 0.0;
636
#endif
637
0
    retval = UA_Variant_setScalarCopy(&value->value, &minInterval, &UA_TYPES[UA_TYPES_DURATION]);
638
0
    if(retval != UA_STATUSCODE_GOOD)
639
0
        return retval;
640
0
    value->hasValue = true;
641
0
    if(includeSourceTimeStamp) {
642
0
        value->hasSourceTimestamp = true;
643
0
        value->sourceTimestamp = el->dateTime_now(el);
644
0
    }
645
0
    return UA_STATUSCODE_GOOD;
646
0
}
647
#endif
648
649
#if defined(UA_GENERATED_NAMESPACE_ZERO) && defined(UA_ENABLE_METHODCALLS) && defined(UA_ENABLE_SUBSCRIPTIONS)
650
static UA_StatusCode
651
resendData(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
652
           const UA_NodeId *methodId, void *methodContext, const UA_NodeId *objectId,
653
           void *objectContext, size_t inputSize, const UA_Variant *input,
654
0
           size_t outputSize, UA_Variant *output) {
655
    /* Get the input argument */
656
0
    if(inputSize != 1 ||
657
0
       !UA_Variant_hasScalarType(input, &UA_TYPES[UA_TYPES_UINT32]))
658
0
        return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
659
0
    UA_UInt32 subscriptionId = *((UA_UInt32*)(input[0].data));
660
661
    /* Get the Session */
662
0
    lockServer(server);
663
0
    UA_Session *session = getSessionById(server, sessionId);
664
0
    if(!session) {
665
0
        unlockServer(server);
666
0
        return UA_STATUSCODE_BADINTERNALERROR;
667
0
    }
668
669
    /* Get the Subscription */
670
0
    UA_Subscription *subscription = getSubscriptionById(server, subscriptionId);
671
0
    if(!subscription) {
672
0
        unlockServer(server);
673
0
        return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
674
0
    }
675
676
    /* The Subscription is not attached to this Session */
677
0
    if(subscription->session != session) {
678
0
        unlockServer(server);
679
0
        return UA_STATUSCODE_BADUSERACCESSDENIED;
680
0
    }
681
682
0
    UA_Subscription_resendData(server, subscription);
683
684
0
    unlockServer(server);
685
0
    return UA_STATUSCODE_GOOD;
686
0
}
687
static UA_StatusCode
688
readMonitoredItems(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
689
                   const UA_NodeId *methodId, void *methodContext, const UA_NodeId *objectId,
690
                   void *objectContext, size_t inputSize, const UA_Variant *input,
691
0
                   size_t outputSize, UA_Variant *output) {
692
    /* Return two empty arrays by default */
693
0
    UA_Variant_setArray(&output[0], UA_Array_new(0, &UA_TYPES[UA_TYPES_UINT32]),
694
0
                        0, &UA_TYPES[UA_TYPES_UINT32]);
695
0
    UA_Variant_setArray(&output[1], UA_Array_new(0, &UA_TYPES[UA_TYPES_UINT32]),
696
0
                        0, &UA_TYPES[UA_TYPES_UINT32]);
697
698
0
    lockServer(server);
699
700
    /* Get the Session */
701
0
    UA_Session *session = getSessionById(server, sessionId);
702
0
    if(!session) {
703
0
        unlockServer(server);
704
0
        return UA_STATUSCODE_BADINTERNALERROR;
705
0
    }
706
0
    if(inputSize == 0 || !input[0].data) {
707
0
        unlockServer(server);
708
0
        return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
709
0
    }
710
711
    /* Get the Subscription */
712
0
    UA_UInt32 subscriptionId = *((UA_UInt32*)(input[0].data));
713
0
    UA_Subscription *subscription = getSubscriptionById(server, subscriptionId);
714
0
    if(!subscription) {
715
0
        unlockServer(server);
716
0
        return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
717
0
    }
718
719
    /* The Subscription is not attached to this Session */
720
0
    if(subscription->session != session) {
721
0
        unlockServer(server);
722
0
        return UA_STATUSCODE_BADUSERACCESSDENIED;
723
0
    }
724
725
    /* Count the MonitoredItems */
726
0
    UA_UInt32 sizeOfOutput = 0;
727
0
    UA_MonitoredItem* monitoredItem;
728
0
    LIST_FOREACH(monitoredItem, &subscription->monitoredItems, listEntry) {
729
0
        ++sizeOfOutput;
730
0
    }
731
0
    if(sizeOfOutput == 0) {
732
0
        unlockServer(server);
733
0
        return UA_STATUSCODE_GOOD;
734
0
    }
735
736
    /* Allocate the output arrays */
737
0
    UA_UInt32 *clientHandles = (UA_UInt32*)
738
0
        UA_Array_new(sizeOfOutput, &UA_TYPES[UA_TYPES_UINT32]);
739
0
    if(!clientHandles) {
740
0
        unlockServer(server);
741
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
742
0
    }
743
0
    UA_UInt32 *serverHandles = (UA_UInt32*)
744
0
        UA_Array_new(sizeOfOutput, &UA_TYPES[UA_TYPES_UINT32]);
745
0
    if(!serverHandles) {
746
0
        unlockServer(server);
747
0
        UA_free(clientHandles);
748
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
749
0
    }
750
751
    /* Fill the array */
752
0
    UA_UInt32 i = 0;
753
0
    LIST_FOREACH(monitoredItem, &subscription->monitoredItems, listEntry) {
754
0
        clientHandles[i] = monitoredItem->parameters.clientHandle;
755
0
        serverHandles[i] = monitoredItem->monitoredItemId;
756
0
        ++i;
757
0
    }
758
0
    UA_Variant_setArray(&output[0], serverHandles, sizeOfOutput, &UA_TYPES[UA_TYPES_UINT32]);
759
0
    UA_Variant_setArray(&output[1], clientHandles, sizeOfOutput, &UA_TYPES[UA_TYPES_UINT32]);
760
761
0
    unlockServer(server);
762
0
    return UA_STATUSCODE_GOOD;
763
0
}
764
#endif /* defined(UA_ENABLE_METHODCALLS) && defined(UA_ENABLE_SUBSCRIPTIONS) */
765
766
static UA_StatusCode
767
writeNs0VariableArray(UA_Server *server, UA_UInt32 id, void *v,
768
1.65k
                      size_t length, const UA_DataType *type) {
769
1.65k
    UA_Variant var;
770
1.65k
    UA_Variant_init(&var);
771
1.65k
    UA_Variant_setArray(&var, v, length, type);
772
1.65k
    return writeValueAttribute(server, UA_NODEID_NUMERIC(0, id), &var);
773
1.65k
}
774
775
#ifdef UA_GENERATED_NAMESPACE_ZERO
776
static UA_StatusCode
777
11.0k
writeNs0Variable(UA_Server *server, UA_UInt32 id, void *v, const UA_DataType *type) {
778
11.0k
    UA_Variant var;
779
11.0k
    UA_Variant_init(&var);
780
11.0k
    UA_Variant_setScalar(&var, v, type);
781
11.0k
    return writeValueAttribute(server, UA_NODEID_NUMERIC(0, id), &var);
782
11.0k
}
783
#endif
784
785
#ifndef UA_GENERATED_NAMESPACE_ZERO
786
static UA_StatusCode
787
addVariableNode(UA_Server *server, char* name, UA_UInt32 variableid,
788
                UA_UInt32 parentid, UA_UInt32 referenceid,
789
                UA_Int32 valueRank, UA_UInt32 dataType) {
790
    UA_VariableAttributes attr = UA_VariableAttributes_default;
791
    attr.displayName = UA_LOCALIZEDTEXT("", name);
792
    attr.dataType = UA_NODEID_NUMERIC(0, dataType);
793
    attr.valueRank = valueRank;
794
    attr.accessLevel = UA_ACCESSLEVELMASK_READ;
795
    return addNode(server, UA_NODECLASS_VARIABLE, UA_NODEID_NUMERIC(0, variableid),
796
                   UA_NODEID_NUMERIC(0, parentid), UA_NODEID_NUMERIC(0, referenceid),
797
                   UA_QUALIFIEDNAME(0, name), UA_NS0ID(BASEDATAVARIABLETYPE),
798
                   &attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES], NULL, NULL);
799
}
800
801
/* A minimal server object that is not complete and does not use the mandated
802
 * references to a server type. To be used on very constrained devices. */
803
static UA_StatusCode
804
minimalServerObject(UA_Server *server) {
805
    /* Server */
806
    UA_StatusCode retval = addObjectNode(server, "Server", UA_NS0ID_SERVER, UA_NS0ID_OBJECTSFOLDER,
807
                                         UA_NS0ID_ORGANIZES, UA_NS0ID_BASEOBJECTTYPE);
808
809
    /* Use a valuerank of -2 for now. The array is added later on and the valuerank set to 1. */
810
    retval |= addVariableNode(server, "ServerArray", UA_NS0ID_SERVER_SERVERARRAY,
811
                              UA_NS0ID_SERVER, UA_NS0ID_HASPROPERTY,
812
                              UA_VALUERANK_ANY, UA_NS0ID_BASEDATATYPE);
813
814
    retval |= addVariableNode(server, "NamespaceArray", UA_NS0ID_SERVER_NAMESPACEARRAY,
815
                              UA_NS0ID_SERVER, UA_NS0ID_HASPROPERTY,
816
                              UA_VALUERANK_ANY, UA_NS0ID_BASEDATATYPE);
817
818
    retval |= addVariableNode(server, "ServerStatus", UA_NS0ID_SERVER_SERVERSTATUS,
819
                              UA_NS0ID_SERVER, UA_NS0ID_HASCOMPONENT,
820
                              UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
821
822
    retval |= addVariableNode(server, "StartTime", UA_NS0ID_SERVER_SERVERSTATUS_STARTTIME,
823
                              UA_NS0ID_SERVER_SERVERSTATUS, UA_NS0ID_HASCOMPONENT,
824
                              UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
825
826
    retval |= addVariableNode(server, "CurrentTime", UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME,
827
                              UA_NS0ID_SERVER_SERVERSTATUS, UA_NS0ID_HASCOMPONENT,
828
                              UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
829
830
    retval |= addVariableNode(server, "State", UA_NS0ID_SERVER_SERVERSTATUS_STATE,
831
                              UA_NS0ID_SERVER_SERVERSTATUS, UA_NS0ID_HASCOMPONENT,
832
                              UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
833
834
    retval |= addVariableNode(server, "BuildInfo", UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO,
835
                              UA_NS0ID_SERVER_SERVERSTATUS, UA_NS0ID_HASCOMPONENT,
836
                              UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
837
838
    retval |= addVariableNode(server, "ProductUri", UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTURI,
839
                              UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT,
840
                              UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
841
842
    retval |= addVariableNode(server, "ManufacturerName",
843
                              UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_MANUFACTURERNAME,
844
                              UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT,
845
                              UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
846
847
    retval |= addVariableNode(server, "ProductName",
848
                              UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTNAME,
849
                              UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT,
850
                              UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
851
852
    retval |= addVariableNode(server, "SoftwareVersion",
853
                              UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_SOFTWAREVERSION,
854
                              UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT,
855
                              UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
856
857
    retval |= addVariableNode(server, "BuildNumber",
858
                              UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDNUMBER,
859
                              UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT,
860
                              UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
861
862
    retval |= addVariableNode(server, "BuildDate",
863
                              UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDDATE,
864
                              UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT,
865
                              UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
866
867
    return retval;
868
}
869
870
#else
871
872
static void
873
551
addModellingRules(UA_Server *server) {
874
    /* Test if the ModellingRules folder was added. (Only for the full ns0.) */
875
551
    UA_NodeId mrNodeId = UA_NS0ID(SERVER_SERVERCAPABILITIES_MODELLINGRULES);
876
551
    const UA_Node *mrnode = UA_NODESTORE_GET(server, &mrNodeId);
877
551
    if(!mrnode)
878
0
        return;
879
551
    UA_NODESTORE_RELEASE(server, mrnode);
880
881
    /* Add ExposesItsArray */
882
551
    addRef(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_MODELLINGRULES),
883
551
           UA_NS0ID(HASCOMPONENT), UA_NS0ID(MODELLINGRULE_EXPOSESITSARRAY), true);
884
885
    /* Add Mandatory */
886
551
    addRef(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_MODELLINGRULES),
887
551
           UA_NS0ID(HASCOMPONENT), UA_NS0ID(MODELLINGRULE_MANDATORY), true);
888
889
890
    /* Add MandatoryPlaceholder */
891
551
    addRef(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_MODELLINGRULES),
892
551
           UA_NS0ID(HASCOMPONENT), UA_NS0ID(MODELLINGRULE_MANDATORYPLACEHOLDER), true);
893
894
    /* Add Optional */
895
551
    addRef(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_MODELLINGRULES),
896
551
           UA_NS0ID(HASCOMPONENT), UA_NS0ID(MODELLINGRULE_OPTIONAL), true);
897
898
    /* Add OptionalPlaceholder */
899
551
    addRef(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_MODELLINGRULES),
900
551
           UA_NS0ID(HASCOMPONENT), UA_NS0ID(MODELLINGRULE_OPTIONALPLACEHOLDER), true);
901
551
}
902
903
#endif
904
905
/* Initialize the nodeset 0 by using the generated code of the nodeset compiler.
906
 * This also initialized the data sources for various variables, such as for
907
 * example server time. */
908
UA_StatusCode
909
551
initNS0(UA_Server *server) {
910
551
    UA_LOCK_ASSERT(&server->serviceMutex);
911
912
    /* Initialize base nodes which are always required an cannot be created
913
     * through the NS compiler */
914
551
    server->bootstrapNS0 = true;
915
551
    UA_StatusCode retVal = createNS0_base(server);
916
917
551
#ifdef UA_GENERATED_NAMESPACE_ZERO
918
    /* Load nodes and references generated from the XML ns0 definition */
919
551
    retVal |= namespace0_generated(server);
920
#else
921
    /* Create a minimal server object */
922
    retVal |= minimalServerObject(server);
923
#endif
924
925
551
    server->bootstrapNS0 = false;
926
927
551
    if(retVal != UA_STATUSCODE_GOOD) {
928
0
        UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
929
0
                     "Initialization of Namespace 0 failed with %s. "
930
0
                     "See previous outputs for any error messages.",
931
0
                     UA_StatusCode_name(retVal));
932
0
        return UA_STATUSCODE_BADINTERNALERROR;
933
0
    }
934
935
    /* NamespaceArray */
936
551
    UA_CallbackValueSource namespaceDataSource = {readNamespaces, writeNamespaces};
937
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_NAMESPACEARRAY),
938
551
                                                  namespaceDataSource);
939
551
    retVal |= writeValueRankAttribute(server, UA_NS0ID(SERVER_NAMESPACEARRAY), 1);
940
941
    /* ServerArray */
942
551
    retVal |= writeNs0VariableArray(server, UA_NS0ID_SERVER_SERVERARRAY,
943
551
                                    &server->config.applicationDescription.applicationUri,
944
551
                                    1, &UA_TYPES[UA_TYPES_STRING]);
945
551
    retVal |= writeValueRankAttribute(server, UA_NS0ID(SERVER_SERVERARRAY), 1);
946
947
    /* ServerStatus */
948
551
    UA_CallbackValueSource serverStatus = {readStatus, writeStatus};
949
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERSTATUS), serverStatus);
950
951
    /* StartTime will be sampled in UA_Server_run_startup()*/
952
953
    /* CurrentTime */
954
551
    UA_CallbackValueSource currentTime = {readCurrentTime, NULL};
955
551
    UA_NodeId currTime = UA_NS0ID(SERVER_SERVERSTATUS_CURRENTTIME);
956
551
    retVal |= setVariableNode_callbackValueSource(server, currTime, currentTime);
957
551
    retVal |= writeMinimumSamplingIntervalAttribute(server, currTime, 100.0);
958
959
    /* State */
960
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERSTATUS_STATE),
961
551
                                         serverStatus);
962
963
    /* BuildInfo */
964
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERSTATUS_BUILDINFO),
965
551
                                         serverStatus);
966
967
    /* BuildInfo - ProductUri */
968
551
    retVal |= setVariableNode_callbackValueSource(server,
969
551
                                         UA_NS0ID(SERVER_SERVERSTATUS_BUILDINFO_PRODUCTURI),
970
551
                                         serverStatus);
971
972
    /* BuildInfo - ManufacturerName */
973
551
    retVal |= setVariableNode_callbackValueSource(server,
974
551
                                         UA_NS0ID(SERVER_SERVERSTATUS_BUILDINFO_MANUFACTURERNAME),
975
551
                                         serverStatus);
976
977
    /* BuildInfo - ProductName */
978
551
    retVal |= setVariableNode_callbackValueSource(server,
979
551
                                         UA_NS0ID(SERVER_SERVERSTATUS_BUILDINFO_PRODUCTNAME),
980
551
                                         serverStatus);
981
982
    /* BuildInfo - SoftwareVersion */
983
551
    retVal |= setVariableNode_callbackValueSource(server,
984
551
                                         UA_NS0ID(SERVER_SERVERSTATUS_BUILDINFO_SOFTWAREVERSION),
985
551
                                         serverStatus);
986
987
    /* BuildInfo - BuildNumber */
988
551
    retVal |= setVariableNode_callbackValueSource(server,
989
551
                                         UA_NS0ID(SERVER_SERVERSTATUS_BUILDINFO_BUILDNUMBER),
990
551
                                         serverStatus);
991
992
    /* BuildInfo - BuildDate */
993
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERSTATUS_BUILDINFO_BUILDDATE),
994
551
                                         serverStatus);
995
996
551
#ifdef UA_GENERATED_NAMESPACE_ZERO
997
998
    /* SecondsTillShutdown */
999
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERSTATUS_SECONDSTILLSHUTDOWN),
1000
551
                                         serverStatus);
1001
1002
    /* ShutDownReason */
1003
551
    UA_LocalizedText shutdownReason;
1004
551
    UA_LocalizedText_init(&shutdownReason);
1005
551
    retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERSTATUS_SHUTDOWNREASON,
1006
551
                               &shutdownReason, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
1007
1008
    /* ServiceLevel */
1009
551
    UA_CallbackValueSource serviceLevel = {readServiceLevel, NULL};
1010
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVICELEVEL), serviceLevel);
1011
1012
    /* ServerDiagnostics - EnabledFlag */
1013
551
#ifdef UA_ENABLE_DIAGNOSTICS
1014
551
    UA_Boolean enabledFlag = true;
1015
#else
1016
    UA_Boolean enabledFlag = false;
1017
#endif
1018
551
    retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_ENABLEDFLAG,
1019
551
                               &enabledFlag, &UA_TYPES[UA_TYPES_BOOLEAN]);
1020
1021
    /* According to Specification part-5 - pg.no-11(PDF pg.no-29), when the
1022
     * ServerDiagnostics is disabled the client may modify the value of
1023
     * enabledFlag=true in the server. By default, this node have
1024
     * CurrentRead/Write access. In CTT, Subscription_Minimum_1/002.js test will
1025
     * modify the above flag. This will not be a problem when build
1026
     * configuration is set at UA_NAMESPACE_ZERO="REDUCED" as NodeIds will not
1027
     * be present. When UA_NAMESPACE_ZERO="FULL", the test will fail. Hence made
1028
     * the NodeId as read only */
1029
551
    retVal |= writeAccessLevelAttribute(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_ENABLEDFLAG),
1030
551
                                        UA_ACCESSLEVELMASK_READ);
1031
1032
    /* Auditing */
1033
551
    UA_CallbackValueSource auditing = {readAuditing, NULL};
1034
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_AUDITING), auditing);
1035
1036
    /* Redundancy Support */
1037
551
    UA_RedundancySupport redundancySupport = UA_REDUNDANCYSUPPORT_NONE;
1038
551
    retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERREDUNDANCY_REDUNDANCYSUPPORT,
1039
551
                               &redundancySupport, &UA_TYPES[UA_TYPES_REDUNDANCYSUPPORT]);
1040
    /* Remove unused subtypes of ServerRedundancy */
1041
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERREDUNDANCY_CURRENTSERVERID), true);
1042
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERREDUNDANCY_REDUNDANTSERVERARRAY), true);
1043
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERREDUNDANCY_SERVERURIARRAY), true);
1044
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERREDUNDANCY_SERVERNETWORKGROUPS), true);
1045
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_CONFORMANCEUNITS), true);
1046
551
    deleteNode(server, UA_NS0ID(SERVER_URISVERSION), true);
1047
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_CONFORMANCEUNITS), true);
1048
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_MAXMONITOREDITEMS), true);
1049
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_MAXMONITOREDITEMSPERSUBSCRIPTION), true);
1050
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_MAXMONITOREDITEMSQUEUESIZE), true);
1051
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_MAXSELECTCLAUSEPARAMETERS), true);
1052
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_MAXSESSIONS), true);
1053
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_MAXSUBSCRIPTIONS), true);
1054
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_MAXSUBSCRIPTIONSPERSESSION), true);
1055
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_MAXWHERECLAUSEPARAMETERS), true);
1056
1057
    /* ServerCapabilities - LocaleIdArray */
1058
551
    UA_LocaleId locale_en = UA_STRING("en");
1059
551
    retVal |= writeNs0VariableArray(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_LOCALEIDARRAY,
1060
551
                                    &locale_en, 1, &UA_TYPES[UA_TYPES_LOCALEID]);
1061
1062
    /* ServerCapabilities - MaxBrowseContinuationPoints */
1063
551
    UA_UInt16 maxBrowseContinuationPoints = UA_MAXCONTINUATIONPOINTS;
1064
551
    retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXBROWSECONTINUATIONPOINTS,
1065
551
                               &maxBrowseContinuationPoints, &UA_TYPES[UA_TYPES_UINT16]);
1066
1067
    /* ServerProfileArray */
1068
551
    UA_String profileArray[3];
1069
551
    UA_UInt16 profileArraySize = 0;
1070
1.65k
#define ADDPROFILEARRAY(x) profileArray[profileArraySize++] = UA_STRING(x)
1071
551
    ADDPROFILEARRAY("http://opcfoundation.org/UA-Profile/Server/StandardUA2017");
1072
551
#ifdef UA_ENABLE_NODEMANAGEMENT
1073
551
    ADDPROFILEARRAY("http://opcfoundation.org/UA-Profile/Server/NodeManagement");
1074
551
#endif
1075
551
#ifdef UA_ENABLE_METHODCALLS
1076
551
    ADDPROFILEARRAY("http://opcfoundation.org/UA-Profile/Server/Methods");
1077
551
#endif
1078
551
    retVal |= writeNs0VariableArray(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_SERVERPROFILEARRAY,
1079
551
                                    profileArray, profileArraySize, &UA_TYPES[UA_TYPES_STRING]);
1080
1081
    /* ServerCapabilities - MaxQueryContinuationPoints */
1082
551
    UA_UInt16 maxQueryContinuationPoints = 0;
1083
551
    retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXQUERYCONTINUATIONPOINTS,
1084
551
                               &maxQueryContinuationPoints, &UA_TYPES[UA_TYPES_UINT16]);
1085
1086
    /* ServerCapabilities - MaxHistoryContinuationPoints */
1087
551
    UA_UInt16 maxHistoryContinuationPoints = 0;
1088
551
    retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXHISTORYCONTINUATIONPOINTS,
1089
551
                               &maxHistoryContinuationPoints, &UA_TYPES[UA_TYPES_UINT16]);
1090
1091
    /* ServerCapabilities - MinSupportedSampleRate */
1092
551
    UA_CallbackValueSource samplingInterval = {readMinSamplingInterval, NULL};
1093
551
    retVal |= setVariableNode_callbackValueSource(server,
1094
551
                                         UA_NS0ID(SERVER_SERVERCAPABILITIES_MINSUPPORTEDSAMPLERATE),
1095
551
                                         samplingInterval);
1096
1097
    /* ServerCapabilities - OperationLimits - MaxNodesPerRead */
1098
551
    UA_CallbackValueSource operationLimitRead = {readOperationLimits, NULL};
1099
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERREAD), operationLimitRead);
1100
1101
    /* ServerCapabilities - OperationLimits - maxNodesPerWrite */
1102
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERWRITE), operationLimitRead);
1103
1104
    /* ServerCapabilities - OperationLimits - MaxNodesPerMethodCall */
1105
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERMETHODCALL), operationLimitRead);
1106
1107
    /* ServerCapabilities - OperationLimits - MaxNodesPerBrowse */
1108
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERBROWSE), operationLimitRead);
1109
1110
    /* ServerCapabilities - OperationLimits - MaxNodesPerRegisterNodes */
1111
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERREGISTERNODES), operationLimitRead);
1112
1113
    /* ServerCapabilities - OperationLimits - MaxNodesPerTranslateBrowsePathsToNodeIds */
1114
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERTRANSLATEBROWSEPATHSTONODEIDS), operationLimitRead);
1115
1116
    /* ServerCapabilities - OperationLimits - MaxNodesPerNodeManagement */
1117
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERNODEMANAGEMENT), operationLimitRead);
1118
1119
    /* ServerCapabilities - OperationLimits - MaxMonitoredItemsPerCall */
1120
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXMONITOREDITEMSPERCALL), operationLimitRead);
1121
1122
    /* Remove unused operation limit components */
1123
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYREADDATA), true);
1124
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYREADEVENTS), true);
1125
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYUPDATEDATA), true);
1126
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYUPDATEEVENTS), true);
1127
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_ROLESET), true);
1128
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_MAXSTRINGLENGTH), true);
1129
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_MAXARRAYLENGTH), true);
1130
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERCAPABILITIES_MAXBYTESTRINGLENGTH), true);
1131
1132
    /* Remove not supported server configurations */
1133
551
    deleteNode(server, UA_NS0ID(SERVER_ESTIMATEDRETURNTIME), true);
1134
551
    deleteNode(server, UA_NS0ID(SERVER_LOCALTIME), true);
1135
551
    deleteNode(server, UA_NS0ID(SERVER_REQUESTSERVERSTATECHANGE), true);
1136
551
    deleteNode(server, UA_NS0ID(SERVER_SETSUBSCRIPTIONDURABLE), true);
1137
551
    deleteNode(server, UA_NS0ID(SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP), true);
1138
551
#ifndef UA_ENABLE_GDS_PUSHMANAGEMENT
1139
551
    deleteNode(server, UA_NS0ID(SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP), true);
1140
551
    deleteNode(server, UA_NS0ID(SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP), true);
1141
551
#endif
1142
1143
1144
551
#ifdef UA_ENABLE_DIAGNOSTICS
1145
    /* ServerDiagnostics - ServerDiagnosticsSummary */
1146
551
    UA_CallbackValueSource serverDiagSummary = {readDiagnostics, NULL};
1147
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY), serverDiagSummary);
1148
1149
    /* ServerDiagnostics - ServerDiagnosticsSummary - ServerViewCount */
1150
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SERVERVIEWCOUNT), serverDiagSummary);
1151
1152
    /* ServerDiagnostics - ServerDiagnosticsSummary - CurrentSessionCount */
1153
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CURRENTSESSIONCOUNT), serverDiagSummary);
1154
1155
    /* ServerDiagnostics - ServerDiagnosticsSummary - CumulatedSessionCount */
1156
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CUMULATEDSESSIONCOUNT), serverDiagSummary);
1157
1158
    /* ServerDiagnostics - ServerDiagnosticsSummary - SecurityRejectedSessionCount */
1159
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SECURITYREJECTEDSESSIONCOUNT), serverDiagSummary);
1160
1161
    /* ServerDiagnostics - ServerDiagnosticsSummary - RejectedSessionCount */
1162
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_REJECTEDSESSIONCOUNT), serverDiagSummary);
1163
1164
    /* ServerDiagnostics - ServerDiagnosticsSummary - SessionTimeoutCount */
1165
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SESSIONTIMEOUTCOUNT), serverDiagSummary);
1166
1167
    /* ServerDiagnostics - ServerDiagnosticsSummary - SessionAbortCount */
1168
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SESSIONABORTCOUNT), serverDiagSummary);
1169
1170
    /* ServerDiagnostics - ServerDiagnosticsSummary - CurrentSubscriptionCount */
1171
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CURRENTSUBSCRIPTIONCOUNT), serverDiagSummary);
1172
1173
    /* ServerDiagnostics - ServerDiagnosticsSummary - CumulatedSubscriptionCount */
1174
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CUMULATEDSUBSCRIPTIONCOUNT), serverDiagSummary);
1175
1176
    /* ServerDiagnostics - ServerDiagnosticsSummary - PublishingIntervalCount */
1177
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_PUBLISHINGINTERVALCOUNT), serverDiagSummary);
1178
1179
    /* ServerDiagnostics - ServerDiagnosticsSummary - SecurityRejectedRequestsCount */
1180
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SECURITYREJECTEDREQUESTSCOUNT), serverDiagSummary);
1181
1182
    /* ServerDiagnostics - ServerDiagnosticsSummary - RejectedRequestsCount */
1183
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_REJECTEDREQUESTSCOUNT), serverDiagSummary);
1184
1185
    /* ServerDiagnostics - SubscriptionDiagnosticsArray */
1186
551
#ifdef UA_ENABLE_SUBSCRIPTIONS
1187
551
    UA_CallbackValueSource serverSubDiagSummary = {readSubscriptionDiagnosticsArray, NULL};
1188
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SUBSCRIPTIONDIAGNOSTICSARRAY), serverSubDiagSummary);
1189
551
#endif
1190
1191
    /* ServerDiagnostics - SessionDiagnosticsSummary - SessionDiagnosticsArray */
1192
551
    UA_CallbackValueSource sessionDiagSummary = {readSessionDiagnosticsArray, NULL};
1193
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SESSIONSDIAGNOSTICSSUMMARY_SESSIONDIAGNOSTICSARRAY), sessionDiagSummary);
1194
1195
    /* ServerDiagnostics - SessionDiagnosticsSummary - SessionSecurityDiagnosticsArray */
1196
551
    UA_CallbackValueSource sessionSecDiagSummary = {readSessionSecurityDiagnostics, NULL};
1197
551
    retVal |= setVariableNode_callbackValueSource(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SESSIONSDIAGNOSTICSSUMMARY_SESSIONSECURITYDIAGNOSTICSARRAY), sessionSecDiagSummary);
1198
1199
#else
1200
    /* Removing these NodeIds make Server Object to be non-complaint with UA
1201
     * 1.03 in CTT (Base Inforamtion/Base Info Core Structure/ 001.js) In the
1202
     * 1.04 specification this has been resolved by allowing to remove these
1203
     * static nodes as well */
1204
    deleteNode(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SESSIONSDIAGNOSTICSSUMMARY), true);
1205
    deleteNode(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY), true);
1206
    deleteNode(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SUBSCRIPTIONDIAGNOSTICSARRAY), true);
1207
#endif
1208
1209
    /* The sampling diagnostics array is optional
1210
     * TODO: Add support for this diagnostics */
1211
551
    deleteNode(server, UA_NS0ID(SERVER_SERVERDIAGNOSTICS_SAMPLINGINTERVALDIAGNOSTICSARRAY), true);
1212
1213
#ifndef UA_ENABLE_PUBSUB
1214
    deleteNode(server, UA_NS0ID(PUBLISHSUBSCRIBE), true);
1215
#endif
1216
1217
#ifndef UA_ENABLE_HISTORIZING
1218
    deleteNode(server, UA_NS0ID(HISTORYSERVERCAPABILITIES), true);
1219
#else
1220
    /* ServerCapabilities - HistoryServerCapabilities - AccessHistoryDataCapability */
1221
551
    retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_ACCESSHISTORYDATACAPABILITY,
1222
551
                               &server->config.accessHistoryDataCapability, &UA_TYPES[UA_TYPES_BOOLEAN]);
1223
1224
    /* ServerCapabilities - HistoryServerCapabilities - MaxReturnDataValues */
1225
551
    retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_MAXRETURNDATAVALUES,
1226
551
                               &server->config.maxReturnDataValues, &UA_TYPES[UA_TYPES_UINT32]);
1227
1228
    /* ServerCapabilities - HistoryServerCapabilities - AccessHistoryEventsCapability */
1229
551
    retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_ACCESSHISTORYEVENTSCAPABILITY,
1230
551
                               &server->config.accessHistoryEventsCapability, &UA_TYPES[UA_TYPES_BOOLEAN]);
1231
1232
    /* ServerCapabilities - HistoryServerCapabilities - MaxReturnEventValues */
1233
551
    retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_MAXRETURNEVENTVALUES,
1234
551
                               &server->config.maxReturnEventValues, &UA_TYPES[UA_TYPES_UINT32]);
1235
1236
    /* ServerCapabilities - HistoryServerCapabilities - InsertDataCapability */
1237
551
    retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_INSERTDATACAPABILITY,
1238
551
                               &server->config.insertDataCapability, &UA_TYPES[UA_TYPES_BOOLEAN]);
1239
1240
    /* ServerCapabilities - HistoryServerCapabilities - InsertEventCapability */
1241
551
    retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_INSERTEVENTCAPABILITY,
1242
551
                               &server->config.insertEventCapability, &UA_TYPES[UA_TYPES_BOOLEAN]);
1243
1244
    /* ServerCapabilities - HistoryServerCapabilities - InsertAnnotationsCapability */
1245
551
    retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_INSERTANNOTATIONCAPABILITY,
1246
551
                               &server->config.insertAnnotationsCapability, &UA_TYPES[UA_TYPES_BOOLEAN]);
1247
1248
    /* ServerCapabilities - HistoryServerCapabilities - ReplaceDataCapability */
1249
551
    retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_REPLACEDATACAPABILITY,
1250
551
                               &server->config.replaceDataCapability, &UA_TYPES[UA_TYPES_BOOLEAN]);
1251
1252
    /* ServerCapabilities - HistoryServerCapabilities - ReplaceEventCapability */
1253
551
    retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_REPLACEEVENTCAPABILITY,
1254
551
                               &server->config.replaceEventCapability, &UA_TYPES[UA_TYPES_BOOLEAN]);
1255
1256
    /* ServerCapabilities - HistoryServerCapabilities - UpdateDataCapability */
1257
551
    retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_UPDATEDATACAPABILITY,
1258
551
                               &server->config.updateDataCapability, &UA_TYPES[UA_TYPES_BOOLEAN]);
1259
1260
    /* ServerCapabilities - HistoryServerCapabilities - UpdateEventCapability */
1261
551
    retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_UPDATEEVENTCAPABILITY,
1262
551
                               &server->config.updateEventCapability, &UA_TYPES[UA_TYPES_BOOLEAN]);
1263
1264
    /* ServerCapabilities - HistoryServerCapabilities - DeleteRawCapability */
1265
551
    retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_DELETERAWCAPABILITY,
1266
551
                               &server->config.deleteRawCapability, &UA_TYPES[UA_TYPES_BOOLEAN]);
1267
1268
    /* ServerCapabilities - HistoryServerCapabilities - DeleteEventCapability */
1269
551
    retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_DELETEEVENTCAPABILITY,
1270
551
                               &server->config.deleteEventCapability, &UA_TYPES[UA_TYPES_BOOLEAN]);
1271
1272
    /* ServerCapabilities - HistoryServerCapabilities - DeleteAtTimeDataCapability */
1273
551
    retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_DELETEATTIMECAPABILITY,
1274
551
                               &server->config.deleteAtTimeDataCapability, &UA_TYPES[UA_TYPES_BOOLEAN]);
1275
551
#endif
1276
1277
551
#if defined(UA_ENABLE_METHODCALLS) && defined(UA_ENABLE_SUBSCRIPTIONS)
1278
551
    retVal |= setMethodNode_callback(server, UA_NS0ID(SERVER_GETMONITOREDITEMS), readMonitoredItems);
1279
551
    retVal |= setMethodNode_callback(server, UA_NS0ID(SERVER_RESENDDATA), resendData);
1280
551
#endif
1281
1282
    /* The HasComponent references to the ModellingRules are not part of the
1283
     * Nodeset2.xml. So we add the references manually. */
1284
551
    addModellingRules(server);
1285
1286
551
#endif /* UA_GENERATED_NAMESPACE_ZERO */
1287
1288
551
    if(retVal != UA_STATUSCODE_GOOD) {
1289
0
        UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
1290
0
                     "Initialization of Namespace 0 (after bootstrapping) "
1291
0
                     "failed with %s. See previous outputs for any error messages.",
1292
0
                     UA_StatusCode_name(retVal));
1293
0
        return UA_STATUSCODE_BADINTERNALERROR;
1294
0
    }
1295
551
    return UA_STATUSCODE_GOOD;
1296
551
}