Coverage Report

Created: 2026-10-05 06:46

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